Tuesday, August 7, 2018

Codeforces 112A Petya and Strings Solution in C (Case-Insensitive Compare)

Petya and Strings (112A) asks you to compare two strings in dictionary order while ignoring upper and lower case. Writing the comparison yourself, instead of reaching for a library function, is a useful exercise in understanding how lexicographic order actually works.

The problem in short

You get two strings of the same length (1 to 100), made of uppercase and lowercase Latin letters. Compare them lexicographically, treating a letter's uppercase and lowercase forms as equal. Print −1 if the first is smaller, 1 if it is larger, and 0 if they are equal.

Full statement: Codeforces 112A – Petya and Strings.

How lexicographic comparison works

Go through both strings position by position. At the first position where the characters differ, whichever string has the smaller character is the smaller string, and you can stop. If you reach the end without finding a difference, the strings are equal. (In general a shorter prefix comes first, but here the lengths are guaranteed equal.)

To ignore case, convert both characters to lowercase with tolower before comparing them.

Examples

  • aaaa vs aaaA: lowercased, both are “aaaa” → 0.
  • abs vs Abz: positions 0 and 1 match; at position 2, ‘s’ < ‘z’ → −1.
  • abcdefg vs AbCdEfF: the first six letters match; then ‘g’ > ‘f’ → 1.

Solution in C

#include <stdio.h>
#include <ctype.h>

int main(void) {
    char a[105], b[105];
    scanf("%s %s", a, b);

    int result = 0;
    for (int i = 0; a[i] != '\0'; i++) {
        char x = tolower((unsigned char)a[i]);
        char y = tolower((unsigned char)b[i]);
        if (x < y) { result = -1; break; }
        if (x > y) { result = 1;  break; }
    }

    printf("%d\n", result);
    return 0;
}

Note the break: once a difference is found, later characters do not matter. Forgetting it means a later position can overwrite the result, which is the most common bug in this problem.

The library shortcut

On Linux, strcasecmp(a, b) from strings.h does a case-insensitive comparison. Be careful: it returns some negative or positive number, not necessarily −1 or 1, so you still need to convert the result. It is also not available on every compiler. The hand-written loop is short and always works.

Complexity

At most one pass over the strings: O(n) time, O(n) memory for the input.

Practice next

Another case-handling string problem: 118A String Task. For working with string length, see 71A Way Too Long Words.

No comments:

Post a Comment