0

basically, I want to try out the persistence bugger and I'm new to java coding so I'm still using NetBeans GUI to code (I know) but I need help to make it work. Have attached my efforts below. The GUI is just a textField that takes input and a button with the given code. If someone could help that would be great. Thanks in advance.

The error I kept getting was: Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 (4 is the length of the number I entered. It kept varying accordingly)

The GUI

long num1=Long.parseLong(jTextField1.getText());
String num2=jTextField1.getText();
char s1;
int pers=1,temp;
for(int i=1;i<=num2.length();i++)
{
  s1=num2.charAt(i);
  temp=Character.getNumericValue(s1);
  pers*=temp;
  if(pers==0)
   {
    System.out.println(i);
    break;
   }
}


String num2=jTextField1.getText();
String test=num2;
char s1;
int pers=num2.length(),temp=1,i,n=0;
  do
  {
      for(i=0;i<pers;i++)
   {
    s1=test.charAt(i);
    temp=temp*(Character.getNumericValue(s1));
   }
    test=Integer.toString(temp);
    temp=1;
  } while(test.length()>1);
  System.out.println(n);

  Final working code:
  long r1=Long.parseLong(jTextField1.getText());
  String s=jTextField1.getText(),s1="";
  long r=1;
  int i=0;
  char[] gfg=s.toCharArray();
  do
   {
    for (char ch : gfg) 
     {
      r *= Character.digit(ch, 10);
     }
      s1=Long.toString(r);
      gfg=s1.toCharArray();
      System.out.println(r);
      r=1;
   }while(s1.length()!=1);
  • Strings in Java go from 0 to length-1, not 1 to length. – markspace Apr 07 '19 at 00:15
  • I know everyone is saying that its 0 to < length but I entered 1 to <= length doesn't that imply that the loop repeats the equal amount of times as 0 to – Amaan Shaikh Apr 07 '19 at 00:28
  • Computers count from 0. So calling `String.charAt(0)` is calling the first character of the String. Calling `array[0]` is calling the first index of the array. Your `IndexOutOfBoundsException` can easily be stopped by changing `for(int i=1; i<=num2.length(); i++){` to `for(int i=0; i – FailingCoder Apr 07 '19 at 00:31
  • Ah 'kay I remember that now will make changes accordingly. Thanks – Amaan Shaikh Apr 07 '19 at 00:32

2 Answers2

1

A simple way to fix your given error is simple.

Computers count from 0. So calling String.charAt(0) is calling the first character of the String. Calling array[0] is calling the first index of the array. Calling String.charAt(1) or array[1] is calling the second element.

Your IndexOutOfBoundsException can easily be stopped by changing

for(int i=1; i<=num2.length(); i++){ to for(int i=0; i<num2.length(); i++){


The reason why your code produces an error is:

When the loop starts, your code skips the first character.

In the last iteration of the for-loop where i == num2.length() causes the problem because you attempt to call the non-existant N+1th character of a string while the length is only N.


The reason why your edited code causes an error is because in the line test=Integer.toString(temp);, you make test become a smaller number. (Probably)

Let's say num2 was 989. Test = num2 and pers = num2.length(), which is 3 This is important.

After this line test=Integer.toString(temp);, test becomes 9. (As a String)

Remember how test is only a single length 1 digit? Well, in the next iteration of the do while loop, inside of the for loop, i to pers is 0 to 3. However, again, test is only a single digit where it's length is 1.

In your for loop try adding System.out.println(test.charAt(i)).


The most important part of code is the logic behind it. If you lose the code you typed but kept a sheet of planning on how to make it, then you can fabricate the code again. If you forget the logic behind the code, and your teacher asks you to explain it, you're going to start from scratch.

The logic behind your code (as described in the title) to multiply each digit in a number is like this.

Input String

Make COUNT integer, equal to 1
Loop: (Use String like char[] array)
    Call String.charAt(int)
    Parse String.charAt(int)
    COUNT (<<placeholder name) *= parsed integer (valueOf returns the Integer wrapper class, you used int instead)
End loop
Print result

Difference between parseInt and valueOf in java?

FailingCoder
  • 757
  • 1
  • 8
  • 20
  • Yes. That is correct. Analyze my "fix" to your code. – FailingCoder Apr 07 '19 at 00:42
  • So basically I took advice from both @FallingCoder and Elliott and I made two separate buttons containing each of your codes and no offense Elliott but yours couldn't handle large numbers while the 0 to – Amaan Shaikh Apr 07 '19 at 00:51
  • While it may seem like it'll take at least an hour to get views on your question, the reality is that it'll only take about 5 seconds or so. – FailingCoder Apr 07 '19 at 00:52
  • Guys I know I shouldn't trouble you all after all that but can you help me find the mistake in this...I'm getting the same error as before. – Amaan Shaikh Apr 07 '19 at 01:47
  • String num2=jTextField1.getText(); String test=num2; char s1; int pers=num2.length(),temp=1,i,n=0; do { for(i=0;i1); System.out.println(n); – Amaan Shaikh Apr 07 '19 at 01:47
  • wait I'll put it in the question – Amaan Shaikh Apr 07 '19 at 01:47
  • @FallingCoder I added the new snippet at the bottom of the question. Please help. – Amaan Shaikh Apr 07 '19 at 01:51
  • What's the problem? – FailingCoder Apr 07 '19 at 01:56
  • @FallingCoder the same error as before. The persistence works for numbers that contain zero and gives the output as 1 but for any other number for example 235, instead of giving 2, it just gives this error again Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 2 – Amaan Shaikh Apr 07 '19 at 02:02
  • In your code, `test.length()` never changes. I didn't manage to find the source of the error though. – FailingCoder Apr 07 '19 at 02:33
  • @FallingCoder but test gets changed to temp right so that changes the length i guess – Amaan Shaikh Apr 07 '19 at 03:40
  • I get it now. I don't see why you changed `test` to effectively be a single character. The source of the problem lies in the fact that `pers` does not change **with** `test`. As a result, when you call `test.charAt(Anything above 0)` it will create an IndexOutOfBounds exception. Why? Because `test` changed to a single character, and you call `test.charAt(pers)` where `pers` is likely above 0. Because `test.charAt(0)` is the first character, and `test.charAt(>0)` calls non-existent characters, it causes this error. (This line changes it: `test=Integer.toString(temp);`) – FailingCoder Apr 07 '19 at 03:51
  • @FallingCoder wait, why should pers keep changing? pers is just used in the for loop right and not anywhere else. Also, in my code its test.charAt(i) and if I'm correct, i goes from 0 to length as you mentioned earlier. So, I don't see where the outofbounds error creeps in... – Amaan Shaikh Apr 07 '19 at 13:11
  • Let's say that `num2` is "12". `pers` would then be 2. You enter the do-while loop and then the for loop. `s1 = temp.charAt(i)`. It doesn't throw an error, because `i=0` and `test` is "12". `s1 = '1'`. `temp *= 1`. Next iteration of the for-loop: `temp *= 2`. No errors yet. After the for-loop, you call **`test=Integer.toString(temp);` which changes test to a single character.** So `test` would be `1`. (String) Because `pers` was equal to `2`, and `test.length()` would be `1`, calling `s1=test.charAt(i);` would cause an error. More specifically, an *`StringIndexOutOfBoundsException`.* – FailingCoder Apr 07 '19 at 15:46
  • Think. I've given you an entire explanation. If you can't do this then I'm going to believe you copied half of this off the internet. – FailingCoder Apr 07 '19 at 19:02
  • I didn't but I know it may sound like it though. Although your explanation makes sense, I really don't understand the part where you explain why the second iteration causes a StringIndexOutOfBoundsException error. Also, I cannot express it enough but I'm really thankful to you for bearing with me. I'm still a dummy so thanks. :) – Amaan Shaikh Apr 07 '19 at 21:24
  • I've completely rewritten my explanation and put it in my answer. I will not re-write it again, and I don't want to edit it either. – FailingCoder Apr 07 '19 at 23:13
  • @FallingCoder Im gonna try putting in i – Amaan Shaikh Apr 08 '19 at 23:33
  • look at the final working code I have added it in the question – Amaan Shaikh Apr 09 '19 at 23:29
  • Why do you need a do-while loop? – FailingCoder Apr 09 '19 at 23:49
0

Your input is already a String, convert it to a char[] and use a for-each loop. Like,

int r = 1;
for (char ch : jTextField1.getText().toCharArray()) {
    r *= Character.digit(ch, 10);
}

Alternatively, valid indices are 0 (inclusive) to length (exclusive). So your for loop should look like

int i=1;i<=num2.length();i++

should be

int i=0; i < num2.length(); i++

Based on your comment below that you need to do it twice, I would extract the logic to a method and call it twice. Like,

private static int multiplyDigits(int r) {
    int t = 1;
    while (r > 0) {
        t *= r % 10;
        r /= 10;
    }
    return t;
}

And then

String str = "4544";
System.out.println(multiplyDigits(multiplyDigits(Integer.parseInt(str))));
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • can you explain in detail what the initial code lines are for? I entered them into the GUI and entered 4544 in jTextField1 and r was 320. I don't understand... – Amaan Shaikh Apr 07 '19 at 00:26
  • But 4*5*4*4 is 320. What did you expect? – Elliott Frisch Apr 07 '19 at 00:33
  • I think he wanted an explanation..? I don't know personally. – FailingCoder Apr 07 '19 at 00:35
  • But then I need the number of times it takes for the multiplication to reach 0. So, do I put that in a loop again and have another variable to count the number of times? – Amaan Shaikh Apr 07 '19 at 00:36
  • @FallingCoder yeah an explanation would have been good but I got it anyway. Thanks. Although the other question I asked still bugs me. Do i need to put that for loop nested inside another one? – Amaan Shaikh Apr 07 '19 at 00:37
  • @AmaanShaikh No. Why would you need a nested loop? – Elliott Frisch Apr 07 '19 at 01:13
  • @ElliottFrisch nested loop because, 4*5*4*4 gives me 320 but that isnt what i need ....I need the output as 2 because 4*5*4*4 = 320 then 3*2*0 = 0 so 2 steps – Amaan Shaikh Apr 07 '19 at 01:50
  • @ElliottFrisch your edited method works but only if I know the number of times the function has to repeat. – Amaan Shaikh Apr 07 '19 at 13:08
  • @AmaanShaikh Next time you ask a question, **please** include ***all* relevant** details **in** the question. – Elliott Frisch Apr 07 '19 at 14:27
  • I'm sorry. Honestly I can't find the error in the latest code and I don't exactly know why. Your method works but isnt enough :\ – Amaan Shaikh Apr 07 '19 at 23:11
  • @ElliottFrisch your code worked...though i had to tweak it a lot....I'll add it in the question so you can look at the masterpiece you have helped to to create. Although, I am certainly not ignoring FallingCoder's help and suggestions. Thanks a lot to both of you. Cheers – Amaan Shaikh Apr 09 '19 at 23:28