문제

I have created a set of algorithms that takes an input of a string vector, checks whether any of the strings occur more than once: if so erases all additional occurrences of the string from the vector, then outputs the new, 'lighter' array without the redundancies.

It works great except now I am to make it case-insensitive; I am attempting to simply add the toupper() std function to the == comparison statement, however it does not seem to work.

I have a more familiar background with Java and am trying to learn C++.
Can someone please show me how to correct my syntax?

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i+1; j < count; j++) {
        if (toupper(list[i]) == toupper(list[j])) {
            list[j] = "";
            count--;
        }
    }

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;
도움이 되었습니까?

해결책

Your loop leaves "holes" in the list array vector, but the size of the array vector does not change (but you decrease your upper bound count)

There are probably many other alternatives, but if you don't want to modify it much, probably you need in an addtional loop to copy non-empty elements from the list array into a new array

Edit: integrating some of the answers

First we're going to have a function to do the toUpper (this is modified from @Jim22150)

std::string stringToUpper(const std::string &input) {
    std::string toBeModified=input;
    std::transform(toBeModified.begin(), toBeModified.end(), toBeModified.begin(), ::toupper);
    return toBeModified;
}

Now, we must not leave holes, so we should use erase (as @Scott Christopher Stauffe indicated):

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i + 1; j < count; j++) {
        if(stringToUpper(list[i]) == stringToUpper(list[j])) {
            list.erase(j,1);
            count--;
        }
    }
}

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << newlist[i];
}
cout << endl << endl;

다른 팁

@DaveS, thanks Dave I will try that; it looks clean and short. However, I found dirtier solution using transform and making a duplicate of the old vector.

    // Output old list.
    cout << endl << "==========\nOld list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << list[i];
    }
    cout << endl << endl;

    // Check uniqueness.
    for (int i = 0; i < count; i++)
        for (int j = i + 1; j < count; j++) {
            std::transform(list[i].begin(), list[i].end(), list[i].begin(), ::toupper);
            std::transform(list[j].begin(), list[j].end(), list[j].begin(), ::toupper);
            if (list[i] == list[j]) {
                newlist[j] = "";
                count--;
            }
        }

    // Output new list.
    cout << endl << "==========\nNew list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << newlist[i];
    }
    cout << endl << endl;

If you want to handle C++ strings as easily as Java strings, then the Boost String Algorithms Library is the way to go. Installing Boost may be a bit hard for a newbie C++ programmer (although it's a breeze compared to many other C++ libraries), but it pays off.

Your problem will essentially be reduced to this:

boost::algorithm::to_upper_copy(list[i]) == boost::algorithm::to_upper_copy(list[j])

I just did a quick google of toupper and I didn't find any string versions of it. The only standard touppper() I have seen is int toupper(int c); - that means you can only use it to compare individual characters! Have you tried stricmp()?

        if ( 0 == _stricmp(list[i], list[j]) ) {
            list[j] = "";
            count--;
        }

Depending on your compiler you may or may not have this function at your disposal.

First of all,

list[j] = ""; // should never work. 

You can remove a char by using erase.

list.erase(j, 1);

Alternatively, to avoid this altogether, you could use a temporary "builder" string and just push_back chars to it when needed.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top