brn
brn

Reputation: 305

Java for loop with char arrays dis-function

I'm stuck with a loop issue here, I'm working on a script who will receive let's say the String "geij" or "abab" and will have to turn it into a double like "6478" or "0101". I do the conversion from letter to number thanks to a two-dimensional array :

String crypt = "geij"; 

char twoD[][] = {{'a','b','c','d','e','f','g','h','i','j'}, {'0','1','2','3','4','5','6','7','8','9'}};

First I pass the String into a char array :

char tab[] = crypt.toCharArray();

Then I use a loop to convert from letter to number :

for(int c=0;c<tab.length;c++) {
    for(int z=0;z<twoD.length;z++) {
        if(tab[c] == twoD[0][z]) {          
            tab[c] = twoD[1][z];
    }
}

Then I create a new instance of String named 'second' to turn the array into a String

String second = new String(tab);

And I turned this String into a double

double finalC = Double.parseDouble(second);

The issue is with this loop, If the String crypt is "abab", the loop will return 0101 as it is supposed to, but if the String contains any letter after "a" or "b" from the first array of the two-dimensional array, like for example the String "geij" the program will simply return "geij". I don't understand why the program doesn't go further than b and it is starting to give me an egghead. If anyone has an idea I'll be grateful !

Here is an example of the inside of the tab array after the loop for the String "abcd" :

Indice : 0 value: 0
Indice : 1 value: 1
Indice : 2 value: c
Indice : 3 value: d

Upvotes: 0

Views: 184

Answers (4)

tom
tom

Reputation: 1493

Since it seems as though in your case the characters are incrementing along with their int values, you don't need a map at all. You can cast the character to an int, and then subtract a's int value. This is a slight variation of B_Osipiuk's answer:

String toEncode = "abcd";
char[] chars = toEncode.toCharArray();
StringBuilder sb = new StringBuilder();
for(char c : chars){
    int newInt = c - 'a';
    if (newInt < 0 || newInt > ('j'-'a')) {
        continue; //or do something else, e.g throw exception;
    }
    sb.append(newInt);
}

System.out.println(sb.toString());

Upvotes: 0

B_Osipiuk
B_Osipiuk

Reputation: 1038

Kevin Cruijssen resolves your problem but you can more:

Use HashMap to this problem. For now, your algorithm time complexity is O(n*m) (n-base string length, m - amount of letters in the table) because you must iterate through the whole array of letters for each letter.

Using HashMap you can find the right letter in O(1). A lot faster. So now your algorithm has O(n) time complexity.

Simple example:

Map<Character, Integer> encoding = new HashMap<>();
encoding.put('a', 0);
encoding.put('b', 1);
encoding.put('c', 2);
encoding.put('d', 3);

String toEncode = "abcd";
char[] chars = toEncode.toCharArray();
StringBuilder sb = new StringBuilder();
for(char c : chars){
    int newInt = encoding.getOrDefault(c, -5); //-5 is just a flag that there is no char to encode
    if(newInt == -5){
       continue; //or do something else, e.g throw exception;
    }
    sb.append(newInt);
}

System.out.println(sb.toString());
//Parse double if you want, but remember that what *Nikolas* said in the comments under your post.
//Double.parseDouble(sb.toString());

Upvotes: 3

Jonasz
Jonasz

Reputation: 21

Length of your twoD array is 2. Your second loop should iterate from z = 0 to twoD[0].length.

Try naming your variables meaningfully so it will be easier to find bugs like this. Also check out foreach loops so you don't have to worry about indexes. Java Maps could be better for mapping characters to numbers.

Upvotes: 0

Kevin Cruijssen
Kevin Cruijssen

Reputation: 9326

The problem is in your inner loop: twoD.length is 2, because twoD contains your two inner array of characters.

You should use twoD[0].length instead:

for(int c=0; c<tab.length; c++) {
  for(int z=0; z<twoD[0].length; z++) {
    ...

However, since you are using all ten digits, perhaps better to use that instead:

char twoD[][] = {{'a','b','c','d','e','f','g','h','i','j'}, {'0','1','2','3','4','5','6','7','8','9'}};
int amountOfDigitsUsed = 10; // Equal to `twoD[0].length` or `twoD[1].length`.

for(int c=0; c<tab.length; c++) {
  for(int z=0; z<amountOfDigitsUsed; z++) {
    ...

Regardless whether you use a hard-coded twoD conversion and amountOfDigits used or not. In your current implementation your twoD.length is 2, causing the issues you have right now.

Upvotes: 0

Related Questions