How to find out the time complexity of any prog - time-complexity

Can anyone help me to get the time complexity of this prog. ? here i have put 3 loop and each loop is dependent on the other one. I mean inner loop is dependent on top inner loop and top inner loop is dependent on outer loop .
public static String getLargestPallindrome(String str)
{ StringBuffer s=new StringBuffer();
for(int i=0;i<str.length()-1;i++) //outer loop
{
for(int j=str.length()-1;j>i;j--) //top inner loop
{
for(int k=i;k<=j;k++){ // inner lopp
s=s.append(str.charAt(k)+"");}
System.out.println("substring is "+s);
System.out.println("hey sub string is "+s.toString()); checkPallindrome(s.toString());
s=s.append(""); s=new StringBuffer();
}
}
return largestPallindrome;
}

There is no easy way to find time complexity by looking at the number of for loops used. You need to understand the code flow and calculate number of computations happened. In this case it is around n*n*(n-1)/2 which makes the time complexity O(n^3) since the highest degree of the polynomial is n^3. Where n is the size of the string str

Thats incorrect when you say it ran only 6 times.
Try putting putting print statments in each loop and you will come to know how many time it executes.
public static String getLargestPallindrome(String str)
{ StringBuffer s=new StringBuffer();
for(int i=0;i<str.length()-1;i++) //outer loop
{
System.out.println("Foo");
for(int j=str.length()-1;j>i;j--) //top inner loop
{
System.out.println("Bar");
for(int k=i;k<=j;k++){ // inner lopp
s=s.append(str.charAt(k)+"");}
System.out.println("substring is "+s);
System.out.println("hey sub string is "+s.toString()); checkPallindrome(s.toString());
s=s.append(""); s=new StringBuffer();
}
}
return largestPallindrome;
}

Related

Time complexity of below program

can anyone pls tell me the time complexity of this func.
this is for generating all valid parenthesis , given the count of pairs
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
My code is working fine, but im not sure about time complexity of it.
pls help
class Solution {
public List generateParenthesis(int n) {
HashMap<String,Boolean> hm = new HashMap<>();
return generate(hm,n);
}
public static List<String> generate(HashMap<String,Boolean> hm, int n ){
if(n == 1){
hm.put("()",true);
List<String>temp = new ArrayList<>();
temp.add("()");
return temp;
}
List<String>temp = generate(hm,n-1);
List<String>ans = new ArrayList<>();
for(String pat : temp){
for(int i = 0; i < pat.length(); i++){
String newPat = pat.substring(0,i)+"()"+pat.substring(i);
if(!hm.containsKey(newPat)){
hm.put(newPat,true);
ans.add(newPat);
}
}
}
return ans;
}
}
You have two for loops, which each run over m and n elements, it can be written as O(m*n), and be contracted to O(n^2) because m can be equal to n.
Your function is recursively calling itself, making time complexity analysis a bit harder.
Think about it this way: You generate all valid parenthesis of length n. It turns out that the number of all valid parenthesis of length n (taking your definition of n) is equal to the nth catalan number. Each string has length 2*n, So the time complexity is not a polynomial, but O(n*C(n)) where C(n) is the nth catalan number.
Edit: It seems like this question is already answered here.

Are there any changes I should make to the formatting of my code?

My teacher is telling me that I need to work on my formatting by using code blocks properly. I've edited the code and would like to know if anyone has any ideas for improvement, or if my code looks ok. I'm just not sure if I am formatting it correctly. I didn't lose many points on the assignment for it, but if there is room for improvement I would greatly appreciate it.
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
int n1 = 0;
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 0;
int i = 1;
System.out.println("Enter a number between 1 and 30 ");
n1 = input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n2= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n3= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n4= input.nextInt();
System.out.println("Enter a number between 1 and 30 ");
n5= input.nextInt();
for(i = 1; i <= n1; i++){
System.out.print("*");
}
System.out.println();//new line
for(i = 1; i <= n2; i++){
System.out.print("*");
}
System.out.println();//new line
for(i = 1; i <= n3; i++){
System.out.print("*");
}
System.out.println();
for(i = 1; i <= n4; i++){
System.out.print("*");
}
System.out.println();
for(i = 1; i <= n5; i++){
System.out.print("*");}
}
System.out.println();
input.close();
}
}
This is what the program looked like before I edited it.
import java.util.Scanner;
public class BarChart
{
public static void main(String[] args)
{
/* Instructor Comments: You need to work on the formatting. Make sure your
code lines up properly. You have most of your code indented too far.
Within the Main method it should be indented one tab stop and
all the code lined up. It should only be indented again if
it is inside another code structure such as an if statement
or for loop. */
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
//initializing variables
int n1 = 0;
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 0;
int i = 1;//index
System.out.println("Enter a number between 1 and 30 ");//prompt user input
/* Instructor Comments: This next line should line up with the rest
of the code and not be indented. */
n1 = input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n2= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n3= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n4= input.nextInt();//store user input
System.out.println("Enter a number between 1 and 30 ");//prompt user input
n5= input.nextInt();//store user input
/* Instructor Comments: Format your for loops properly. The code blocks
should be on there own line. Not on the same line as the code inside it.
I am fixing the first one to show you. */
for(i = 1; i <= n1; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{
System.out.print("*");
}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n2; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n3; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n4; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
for(i = 1; i <= n5; i++)//starts loop at one, loop counts up to the integer the user incremented, increments up to users input one at a time
{System.out.print("*");}//prints corresponding amount of *'s based on how many times the loop incremented
System.out.println();//new line
input.close();//closes scanner
}
}
One thing to note about formatting code is that most of the time, the format of code does not impact how it runs. (In some cases you could write most of your code on one line and it would still work).
Formatting is one of those things that is designed to make it easier on the developer to debug and change or add code. With this in mind, everyone can format their code in whatever way they find it suits them. You shouldn't have lost marks for a piece of code that does work.
Here are some well-known practices of formatting code:
Hierarchical
Think of this as a hierarchy. If you place an object within a class, or a function within a function, you format it to represent that.
For example:
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
Would become:
import java.util.Scanner;
public class BarChart{
public static void main(String[] args){
See how this represents that public static void main(String[] args){ is within public class BarChart{? It makes it a lot easier to see it visually. Use your parentheses to represent a closure of a function, and indent it at the same level as the declaration. Of course, this brings up the never-ending debate about whether you use tab or space to indent your code, but really - it doesn't matter. It's your choice.
Spacing
I once read somewhere that if you believe a comment would be most suitable in between two lines of code, leave a gap. This especially applies between two different functions or the like (which it appears you've already done).
Commenting
Ah, commenting. It's saved me from hours of trying to remember why I wrote something like that, or why something wasn't working. Always try to comment your code. It's the one time you can convert all the computer language into human-readable language and it will help you better understand your code. If you need to pass the code on, the new developer will be able to understand it better. If you need to fix something a year later, you will be able to recall how it worked and possibly what needs to be changed. Comment, comment, comment.
These are just some of my favourite practices and some you should adapt too. These are by no means professional practices and they're just the basics of coding. To answer your original question, your code is very well structured but try to focus on indenting and commenting.
(Note: if you were talking about the structure of your code and not the format, you should look into not repeating functions. This makes your code look bulky).
They probably meant for you to use loops when you need to repeat certain patterns. Your main function can be rewritten like this:
public static void main(String[] args) {
System.out.println("Riley Hall - Assignment 3\n");
Scanner input = new Scanner(System.in);
int[] n = new int[5];
int i, j;
for (i = 0; i < 5; i++) {
System.out.println("Enter a number between 1 and 30 ");
n[i] = input.nextInt();
}
for (i = 0; i < 5; i++) {
for (j = 0; j < n[i]; j++) {
System.out.print("*");
}
System.out.println();
}
input.close();
}
As you can see, I used loop variables starting from zero index and ending before the array size is reached. This is generally considered good practice, because arrays, for example, start with index 0. If you really want to impress your teacher, you can use methods as well:
private static int[] readNumbers(int amount) {
Scanner input = new Scanner(System.in);
int[] n = new int[amount];
int i;
for (i = 0; i < 5; i++) {
System.out.println("Enter a number between 1 and 30 ");
n[i] = input.nextInt();
}
input.close();
return n;
}
private static void printStars(int[] amounts) {
int i, j;
for (i = 0; i < amounts.length; i++) {
for (j = 0; j < amounts[i]; j++) {
System.out.print("*");
}
System.out.println();
}
}
public static void main(String[] args) {
System.out.println("Riley Hall - Assignment 3\n");
int[] n = readNumbers(5);
printStars(n);
}
They make code reusable and are infinitely useful.
As per formatting, you can always get IntelliJ IDEA community edition and use its auto format feature to see how a generally good formatting looks. You shouldn't rely on this though to do the job for you until you're comfortable with keeping the format yourself.

Sage: Iterate over increasing sequences

I have a problem that I am unwilling to believe hasn't been solved before in Sage.
Given a pair of integers (d,n) as input, I'd like to receive a list (or set, or whatever) of all nondecreasing sequences of length d all of whose entries are no greater than n.
Similarly, I'd like another function which returns all strictly increasing sequences of length d whose entries are no greater than n.
For example, for d = 2 n=3, I'd receive the output:
[[1,2], [1,3], [2,3]]
or
[[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
depending on whether I'm using increasing or nondecreasing.
Does anyone know of such a function?
Edit Of course, if there is such a method for nonincreasing or decreasing sequences, I can modify that to fit my purposes. Just something to iterate over sequences
I needed this algorithm too and I finally managed to write one today. I will share the code here, but I only started to learn coding last week, so it is not pretty.
Idea Input=(r,d). Step 1) Create a class "ListAndPosition" that has a list L of arrays Integer[r+1]'s, and an integer q between 0 and r. Step 2) Create a method that receives a ListAndPosition (L,q) and screens sequentially the arrays in L checking if the integer at position q is less than the one at position q+1, if so, it adds a new array at the bottom of the list with that entry ++. When done, the Method calls itself again with the new list and q-1 as input.
The code for Step 1)
import java.util.ArrayList;
public class ListAndPosition {
public static Integer r=5;
public final ArrayList<Integer[]> L;
public int q;
public ListAndPosition(ArrayList<Integer[]> L, int q) {
this.L = L;
this.q = q;
}
public ArrayList<Integer[]> getList(){
return L;
}
public int getPosition() {
return q;
}
public void decreasePosition() {
q--;
}
public void showList() {
for(int i=0;i<L.size();i++){
for(int j=0; j<r+1 ; j++){
System.out.print(""+L.get(i)[j]);
}
System.out.println("");
}
}
}
The code for Step 2)
import java.util.ArrayList;
public class NonDecreasingSeqs {
public static Integer r=5;
public static Integer d=3;
public static void main(String[] args) {
//Creating the first array
Integer[] firstArray;
firstArray = new Integer[r+1];
for(int i=0;i<r;i++){
firstArray[i] = 0;
}
firstArray[r] = d;
//Creating the starting listAndDim
ArrayList<Integer[]> L = new ArrayList<Integer[]>();
L.add(firstArray);
ListAndPosition Lq = new ListAndPosition(L,r-1);
System.out.println(""+nonDecSeqs(Lq).size());
}
public static ArrayList<Integer[]> nonDecSeqs(ListAndPosition Lq){
int iterations = r-1-Lq.getPosition();
System.out.println("How many arrays in the list after "+iterations+" iterations? "+Lq.getList().size());
System.out.print("Should we stop the iteration?");
if(0<Lq.getPosition()){
System.out.println(" No, position = "+Lq.getPosition());
for(int i=0;i<Lq.getList().size();i++){
//Showing particular array
System.out.println("Array of L #"+i+":");
for(int j=0;j<r+1;j++){
System.out.print(""+Lq.getList().get(i)[j]);
}
System.out.print("\nCan it be modified at position "+Lq.getPosition()+"?");
if(Lq.getList().get(i)[Lq.getPosition()]<Lq.getList().get(i)[Lq.getPosition()+1]){
System.out.println(" Yes, "+Lq.getList().get(i)[Lq.getPosition()]+"<"+Lq.getList().get(i)[Lq.getPosition()+1]);
{
Integer[] tempArray = new Integer[r+1];
for(int j=0;j<r+1;j++){
if(j==Lq.getPosition()){
tempArray[j] = new Integer(Lq.getList().get(i)[j])+1;
}
else{
tempArray[j] = new Integer(Lq.getList().get(i)[j]);
}
}
Lq.getList().add(tempArray);
}
System.out.println("New list");Lq.showList();
}
else{
System.out.println(" No, "+Lq.getList().get(i)[Lq.getPosition()]+"="+Lq.getList().get(i)[Lq.getPosition()+1]);
}
}
System.out.print("Old position = "+Lq.getPosition());
Lq.decreasePosition();
System.out.println(", new position = "+Lq.getPosition());
nonDecSeqs(Lq);
}
else{
System.out.println(" Yes, position = "+Lq.getPosition());
}
return Lq.getList();
}
}
Remark: I needed my sequences to start at 0 and end at d.
This is probably not a very good answer to your question. But you could, in principle, use Partitions and the max_slope=-1 argument. Messing around with filtering lists of IntegerVectors sounds equally inefficient and depressing for other reasons.
If this has a canonical name, it might be in the list of sage-combinat functionality, and there is even a base class you could perhaps use for integer lists, which is basically what you are asking about. Maybe you could actually get what you want using IntegerListsLex? Hope this proves helpful.
This question can be solved by using the class "UnorderedTuples" described here:
http://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tuple.html
To return all all nondecreasing sequences with entries between 0 and n-1 of length d, you may type:
UnorderedTuples(range(n),d)
This returns the nondecreasing sequence as a list. I needed an immutable object (because the sequences would become keys of a dictionary). So I used the "tuple" method to turn the lists into tuples:
immutables = []
for s in UnorderedTuples(range(n),d):
immutables.append(tuple(s))
return immutables
And I also wrote a method which picks out only the increasing sequences:
def isIncreasing(list):
for i in range(len(list) - 1):
if list[i] >= list[i+1]:
return false
return true
The method that returns only strictly increasing sequences would look like
immutables = []
for s in UnorderedTuples(range(n),d):
if isIncreasing(s):
immutables.append(tuple(s))
return immutables

How to use the value of a return statement in a different method?

I recently started codeing java, so this question might be a little, well, stupid, but i created a small program that averages 5 numbers. I know the program is very over complicated, i have just been trying out some of the new things i've learned.My problem is i would like to get the variable "Answer" up in my main program. I dont want to change around the program if i dont have to.I have returned the value in the average method, and set this answer to the variable Answer, but how can i use System.out.print(Answer) or print the return. Heres the code! Sorry if its not in a code block, i indented 4 spaces, but it doesnt say anything.
package Tests;
import java.util.*;
public class average_Test {
static double Total=0;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int temp;
int count[]={5,1,2,3,4};
for(int x:count){
System.out.print("Please enter 5 numbers: ");
temp=scan.nextInt();
average(temp);
}
}
public static double average(int n){
for(int c=0;c<1;c++){
Total+=n;
}
double average=Total/5;
System.out.println(average);
double Answer = Total/5;
return Total/5;
}
}
You can use variable binding, or print result of function:
double a = average(temp);
System.out.println(a);
or:
System.out.println(average(temp));
At the end it will look like this:
double result = 0;
System.out.print("Please enter 5 numbers: ");
for (int x : count) {
temp = scan.nextInt();
result = average(temp);
}
System.out.println(result);
P.S. code looks weird, consider implementing double average(int[] numbers)

Why is java program skipping my inner loop?

Hello I'm a beginning programming Student and I am practicing using loops to validate input. Unfortunately, the loop works but skips the inner loop entirely... I get now error message or prompt...
Here is my code: [I BORROWED IT FROM AN ANSWER ON THIS SITE ABOUT VALIDATING INPUT SO I COULD TEST IT.]
import java.util.Scanner;
public class ValidationTest
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int number;
do {
System.out.println("Please enter a positive number!");
while (!sc.hasNextInt())
{
System.out.println("That's not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
} while (number <= 0);
System.out.println("Thank you! Got " + number);
}
}
The inner loop :
while (!sc.hasNextInt())
{
System.out.println("That's not a number!");
sc.next(); // this is important!
}
number = sc.nextInt();
only check if your input is not a number, if you input -123, the function !sc.hasNextInt() is false so it'll skip the loop, if you want to check the number is negative, add this check after the assign number value:
if(number <= 0 ){
System.out.println("The number is negative!");
}
You don't have to make another loop for checking the number is negative or not because of the first loop had it, and do...while loop will make sure you have to run the loop at least one time
The while loop will be skipped if the condition (in parentheses after while) is false when the while loop is first executed.
You can use a debugger to step through the code to see what is going on.
If you do not know how to use a debugger, stop everything you are doing and do some Google searches or whatever you need to do to find out how to use one.
your int number is NaN (not a number). Try setting it to -1, so you can enter the first loop.
In second loop sc didn't ever scan for input it's only initialized.