我可以走到数组边界之外

I Am Able To Go Outside Array Bounds

本文关键字:边界 数组 我可以      更新时间:2023-10-16

给定两个字符串,编写一个方法来确定其中一个是否是另一个字符串的变位/排列。这是我的方法:

我写了这个函数来检查两个字符串是否为字谜(如dog和god)。

在ascii中,a到z是97 - 122。

基本上,我有一个初始值都为false的bool数组。每次在string1中遇到char时,它都会将其标记为true。

要检查它是否是一个变位,我检查string2中是否有任何字符为假(如果在string1中遇到,应该为真)。

我不知道如何,但这也是工作的:arr[num] = true;(不应该工作,因为我没有考虑到ascii从97开始,因此越界)。

(旁注:有比我更好的方法吗?)

编辑:感谢所有的回复!我会仔细阅读每一封。顺便说一下,这不是作业。这是一个来自编程面试练习书的问题

bool permutation(const string &str1, const string &str2)
{
    // Cannot be anagrams if sizes are different
    if (str1.size() != str2.size())
        return false;
    bool arr[25] = { false };
    for (int i = 0; i < str1.size(); i++) // string 1
    {
        char ch = (char)tolower(str1[i]); // convert each char to lower
        int num = ch; // get ascii
        arr[num-97] = true; 
    }
    for (int i = 0; i < str2.size(); i++) // string 2
    {
        char ch = (char)tolower(str2[i]); // convert char to lower
        int num = ch; // get ascii
        if (arr[num-97] == false) 
            return false;
    }
    return true;
}

c++数组中没有任何固有的东西阻止您在数组末尾以外进行写入。但是,在这样做时,您违反了与编译器的契约,因此它可以自由地做它想做的事情(未定义行为)。

你可以通过使用vector类对"数组"进行边界检查,如果这是你需要的。

至于更好的方法,如果你的数组足够大,可以覆盖每个可能的字符(这样你就不必担心边界检查),并且它不应该是一个真值,而应该是一个计数,以便处理字符串中的重复字符。如果它只是一个真值,那么hereher将被认为是字谜。

即使你声明它是不是赋值,如果你自己实现它,你仍然会学到更多,所以它只是来自我的伪代码。基本思路是:

def isAnagram (str1, str2):
    # Different lengths means no anagram.
    if len(str1) not equal to len(str2):
        return false
    # Initialise character counts to zero.
    create array[0..255] (assumes 8-bit char)
    for each index 0..255:
        set count[index] to zero
    # Add 1 for all characters in string 1.
    for each char in string1:
        increment array[char]
    # Subtract 1 for all characters in string 2.
    for each char in string2:
        decrement array[char]
    # Counts will be all zero for an anagram.
    for each index 0..255:
        if count[index] not equal to 0:
            return false
    return true

工作方式:零额外成本。

bool permutation(const std::string &str1, const std::string &str2)
{
    // Cannot be anagrams if sizes are different
    if (str1.size() != str2.size())
        return false;
    int arr[25] = {0 };
    for (int i = 0; i < str1.size(); i++) // string 1
    {
        char ch = (char)tolower(str1[i]); // convert each char to lower
        int num = ch; // get ascii
        arr[num-97] = arr[num-97] + 1 ;
    }
    for (int i = 0; i < str2.size(); i++) // string 2
    {
        char ch = (char)tolower(str2[i]); // convert char to lower
        int num = ch; // get ascii
        arr[num-97] = arr[num-97] - 1 ;
    }
    for (int i =0; i< 25; i++) {
        if (arr[i] != 0) {
            return false;
        }
    }
    return true;
}

是的,CC++都不执行index-out-of-bounds

程序员有责任确保程序逻辑不越过合法的限制。程序员需要检查是否违反

<

改进代码/strong>:

bool permutation(const string &str1, const string &str2)
{
    // Cannot be anagrams if sizes are different
    if (str1.size() != str2.size())
        return false;
    int arr[25] = { 0 };                  //<-------- Changed
    for (int i = 0; i < str1.size(); i++) // string 1
    {
        char ch = (char)tolower(str1[i]); // convert each char to lower
        int num = ch; // get ascii
        arr[num-97] += 1;                 //<-------- Changed
    }
    for (int i = 0; i < str2.size(); i++) // string 2
    {
        char ch = (char)tolower(str2[i]); // convert char to lower
        int num = ch; // get ascii
        arr[num-97] = arr[num-97] - 1 ;   //<-------- Changed
    }
    for (int i =0; i< 25; i++) {          //<-------- Changed
        if (arr[i] != 0) {                //<-------- Changed
            return false;                 //<-------- Changed
        }
    }       
    return true;
}