0

I've got an assignment to write a a method that accepts two strings as an argument and returns a value of 1, 0, -1 (respectively) if the first string is lexicographicaly before, equal or after the second string, using only the charAt() and length() methods from the String class.

The problem is that even though I initialized an int variable in my for loop, it won't recognize them later in the loop when using the charAt() method. The compiler keeps saying "unexpected type. required: variable; found: value" (using BlueJ).

public class Word {

    private String _st;

    /**
     * range small letters: a = 97, z = 122.
     * 
     * range capital letters: A = 65, Z = 90.
     */
    public int myCompare(String s1, String s2) {
        char[] alphabet = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

        //1st loop i;
        //2nd loop j;
        //3rd loop k;
        for (int i = 0; i < s1.length(); i++) {
            _st = new String (s1);
            if (_st.charAt(i) < 97) {
               _st.charAt(i) += 32;
            }

            for (int j = 0; alphabet[j] == _st.charAt(i); j++) {
                int x = alphabet[j];
                _st.charAt(i) = x;
            }
        }
        return 1; // temporaray.
        /*
        if (s1.charAt(0) < s2.charAt(0)) {
            return 1;
        }
        else if (s1.charAt(0) > s2.charAt(0)) {
            return -1;
        }
        else {
            return 0;
        }*/
    }
}

So what exactly am I doing wrong? Thanks for any help.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • I'd do `if(_st.charAt(i) < 90)`, because _ ((char)95) shouldn't be turned into ((char) 127)! Also, couldn't you just use `_st.toUpperCase()` ? – Charlie Dec 28 '14 at 15:36
  • You could have saved loads of typing if you had written `char[] alphabet = "abcd...wxyz".toCharArray()` instead of `char[] alphabet = {'a', 'b', 'c', 'd', ..., 'w', 'x', 'y', 'z'}` — provided that you have typed it yourself. – MC Emperor Dec 28 '14 at 15:38
  • @MCEmperor Or `char[] alphabet=new char[27];for(char c='a';c<='z';c++)alphabet[c-'a']=c;`. That's my favorite, as you don't have to smack every key on your keyboard for that. (Some of my keys are broken, and I wouldn't recommend `char[] x={'p', (char)('p'+1), 'r'}` ) – Charlie Dec 28 '14 at 15:42
  • That's true. But [this answer on a question](http://stackoverflow.com/a/17575926/507738) states that it's cleaner. – MC Emperor Dec 28 '14 at 15:48
  • You should refine what you mean by "lexicographically" and the allowed content of the strings. Unless you have studied Unicode (character set used by Java, .NET, ...) and UTF-16 (encoding used by Java, ... strings), it is probably sufficient to compare `String.charAt()` directly as `char` (an [integral type](http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.2)) and compare strings as `char` sequences lexicographically. In general, strings use esoteric Unicode features; And, alphabetic sorting order is language and culture dependent, and has preferences like case-sensitivity. – Tom Blodget Dec 28 '14 at 18:33

4 Answers4

3

_st.charAt(i) += 32;

this is meaningless.

_st.charAt(i) returns a char. Adding 32 to that char has no meaning if you don't store the result in some variable.

You can replace it with :

 char c = _st.charAt(i);
 c += 32;
Eran
  • 387,369
  • 54
  • 702
  • 768
1

Besides, that _st.charAt(i) += 32; does nothing with the result, your algorithm is a little bit complicated. You should do the comparison with the two strings in place and not via an alphabet:

public static int myCompare(String string1, String string2) {
    int result = 0;
    int differenceCases='a'-'A';
    int end = (string1.length() > string2.length())
            ? string2.length()
            : string1.length();
    for (int index = 0; index < end; index += 1) {
        int char1=(string1.charAt(index)>'Z')?(string1.charAt(index)-differenceCases):(string1.charAt(index));
        int char2=(string2.charAt(index)>'Z')?(string2.charAt(index)-differenceCases):(string2.charAt(index));
        int difference = char1-char2;
        if (difference == 0 || abs(difference) == differenceCases) continue;
        return (difference < 0) ? 1 : -1;
    }
    return result;
}

1) You should take care which one of the two strings is the longer one, to prevent Out of bounds problems.

int end = (string1.length() > string2.length())
            ? string2.length()
            : string1.length();

2) You could make use of the ASCII-Values of the two strings.

2aa) Calculate different positions

2ab) Make sure, you have the same case for comparison

int char1=(string1.charAt(index)>'Z')?(string1.charAt(index)-differenceCases):(string1.charAt(index));

If it is lowercase substract the difference between cases ('a'-'A').

2ba) If the difference is 0, you have two chars of the same kind.

2bb) If the absolute difference is 'a'-'A', you have the same letter, but mixed cases

2bc) In each case, it is no difference, so skip to the next letter

2c) If you have a difference, which is greater than 'a'-'A', check if it is negative, so string2.charAt(i) is greater than string1.charAt(i), which means it comes after.

Thomas Junk
  • 5,588
  • 2
  • 30
  • 43
0

enjoy this working methode

public static int compareWords(String mot1,String mot2){

    String toLowerCase = mot1.toLowerCase();
    String toLowerCase1 = mot2.toLowerCase();
    int answer=0,lenght=(mot1.length()<mot2.length())?mot1.length():mot2.length();

    for (int i = 0; i < lenght; i++) {

        if (toLowerCase.charAt(i)<toLowerCase1.charAt(i)) {
            answer=1;
          //  System.out.println("loop1:"+answer);
        }else{
            if (toLowerCase.charAt(i)>toLowerCase1.charAt(i)) {

            answer=-1;
            break;
            }
        }
    }
    if (answer==0) {
        if (mot1.length()<mot2.length()) {
            answer=1;
         //   System.out.println("if1:"+answer);
        }else {
            if (mot1.length()==mot2.length()) {
                answer=0;
            }else answer=-1;
        }
    }
   // System.out.println("answer:"+answer);
    return answer;
}
0

You can have a look at java.lang.String.compareTo() and java.lang.String.compareToIgnoreCase()? If you are ok to use standard Java library functions, you can use those directly, if not, you can refer to implementations of the same.

I know it's a shortcut, but it'll provide you a better understanding.