1

while ループで 2 つの文字列を比較しようとしています。コードのスニペットを次に示します。

//variables
string pivot, array[10];
int rightBoundary;

//loop
while( pivot < array[rightBoundary]) 

このコードはクイックソートのチュートリアルからのものですが、文字列で動作するように変換しようとしています。

だから私の質問は、この比較を行うための最良の方法は何ですか.

現在、このエラーが発生します (quickSortNumbers.exe の 0x774215de で未処理の例外: 0xC0000005: 場所 0x965b7214 を読み取るアクセス違反)。

そして助けは素晴らしいでしょう:)

編集:申し訳ありませんが、すべてのコードをアップロードする必要がありました。問題は実際には文字列配列である可能性があります。すべての私のコードをここに示します:

#include <iostream>
#include <string>
using namespace std;

#define array1_SIZE 5                //change the array1 size here

void Printarray1(string* array1, int n);
void QuickSort(string* array1, int startIndex, int endIndex);
int Splitarray1(string* array1, string pivot, int startIndex, int endIndex);
void swap(string &a, string &b);

int main(void)
{
    string array1[array1_SIZE];
    int i;

    for( i = 0; i < array1_SIZE; i++)               //array1 elements input
    {
        cout<<"Enter an integer : ";
        cin>>array1[i];
    }

    cout<<endl<<"The list you input is : "<<endl;
    Printarray1(array1, array1_SIZE);
    QuickSort(array1,0,array1_SIZE - 1);    //sort array1 from first to last element
    cout<<endl<<"The list has been sorted, now it is : "<<endl;
    Printarray1(array1, array1_SIZE);

    cin.get();
    cin.get();
    int read;
    cin >> read;
    return 0;
}

/* This function swaps two numbers
  Arguments :
           a, b - the numbers to be swapped
  */
void swap(string &a, string &b)
{
    string temp;
    temp = a;
    a = b;
    b = temp;
}

/* This function prints an array1.
  Arguments :
           array1 - the array1 to be printed
           n - number of elements in the array1
  */
void Printarray1(string* array1, int n)
{
    int i;

    for( i = 0; i < n; i++) 
    {   
        cout << array1[i] << '\t';
    }
}

/* This function does the quicksort
  Arguments :
           array1 - the array1 to be sorted
           startIndex - index of the first element of the section
           endIndex - index of the last element of the section
  */
void QuickSort(string* array1, int startIndex, int endIndex)
{
    string pivot = array1[startIndex];  //pivot element is  the leftmost element
    int splitPoint;

    if(endIndex > startIndex)       //if they are equal, it means there is
        //only one element and quicksort's job
        //here is finished
    {
        splitPoint = Splitarray1(array1, pivot, startIndex, endIndex);
        //Splitarray1() returns the position where
        //pivot belongs to
        array1[splitPoint] = pivot;
        QuickSort(array1, startIndex, splitPoint-1);   //Quick sort first half
        QuickSort(array1, splitPoint+1, endIndex);   //Quick sort second half
    }
}

/* This function splits the array1 around the pivot
  Arguments :
           array1 - the array1 to be split
           pivot - pivot element whose position will be returned
           startIndex - index of the first element of the section
           endIndex - index of the last element of the section
  Returns :
         the position of the pivot
  */
int Splitarray1(string* array1, string pivot, int startIndex, int endIndex)
{
    int leftBoundary = startIndex;
    int rightBoundary = endIndex;

    while(leftBoundary < rightBoundary) //shuttle pivot until the     boundaries meet
    {
        while( pivot < array1[rightBoundary]//keep moving until a lesser element is found
               && rightBoundary > leftBoundary)   //or until the  leftBoundary is reached
        {
            rightBoundary--;                        //move left
        }
        swap(array1[leftBoundary], array1[rightBoundary]);
        //Printarray1(array1, array1_SIZE);          //Uncomment this line for study

        while( pivot >= array1[leftBoundary]          //keep moving until a greater or equal element is found
               && leftBoundary < rightBoundary)   //or until the rightBoundary is reached
        {
            leftBoundary++;                      //move right
        }
        swap(array1[rightBoundary], array1[leftBoundary]);
        //Printarray1(array1, array1_SIZE);          //Uncomment this line for study
    }
    return leftBoundary;                              //leftBoundary is the split point because
    //the above while loop exits only when 
    //leftBoundary and rightBoundary are equal
}
4

2 に答える 2

2

おそらく初期化していないことが原因で、範囲外エラーが発生している可能性がありますrightBoundary。文字列は、比較演算子を使用して完全に比較できます。

#include <iostream>
using std::cout;

#include <string>
using std::string;

int main()
{
    string s1 = "hello";
    string s2 = "world!";

    string lower = s1 < s2 ? s1 : s2;

    cout << lower; //prints "hello"
}

大文字と小文字を気にせずに比較するにlexicographical_compareは、独自の比較機能を使用できます。

#include <algorithm>
using std::lexicographical_compare;

#include <cctype>
using std::tolower;

#include <iostream>
using std::cout;

#include <string>
using std::string;

bool nocase_compare (char one, char two)
{
    return tolower (one) < tolower (two);
}

int main()
{
    string s1 = "Hello";
    string s2 = "happy";

    if (lexicographical_compare (s1.begin(), s1.end(), s2.begin(), s2.end(), nocase_compare))
        cout << s1;
    else
        cout << s2;
    //prints "happy" even though 'H' < 'h'
}

< と > を本当に使用したい場合は、バージョンのとstringを実装するための小さなラッパーを作成する必要があります。実装されているものはデフォルトを使用しています。operator<operator>stringlexicographical_compare

于 2012-04-21T15:21:09.187 に答える
1

文字列の比較に < を使用することは問題ありませんが、アルファベット順が必要な場合は期待どおりにならない可能性があります。辞書編集順序が必要な場合は、すべての小文字が大文字の前に来るため、代わりに lexicographical_compare を使用する必要があります。

コードがクラッシュする理由は、rightBoundary に初期値を割り当てていないためです。次のようにする必要があります。

int rightBoundary = 0;

それ以外の場合、rightBoundary は任意の初期値を持つため、圧倒的な確率で「配列」のサイズよりも大きくなり、範囲外のアクセスが発生します。

于 2012-04-21T15:23:02.433 に答える