这两个操作在 C++ 中不是一回事吗?

Posted

技术标签:

【中文标题】这两个操作在 C++ 中不是一回事吗?【英文标题】:Isn't these two operations the same thing in C++? 【发布时间】:2021-05-27 16:45:42 【问题描述】:

我已经声明了一个bool 类型的二维数组,我想用false 启动它。我对此代码有此要求(如下所示),这是关于“Wild Card String Matching”的问题

我尝试了 2 种方法来使用 false 初始化布尔矩阵。第一种方法是bool lookup[n + 1][m + 1]=false;,第二种方法是memset(lookup, false, sizeof(lookup));

当我测试我的代码时,第一种方法是给我一个错误的答案。为什么会这样?我已附上我的代码。

// C++ program to implement wildcard
// pattern matching algorithm
#include <bits/stdc++.h>
using namespace std;

// Function that matches input str with
// given wildcard pattern
bool strmatch(char str[], char pattern[], int n, int m)

    

    // lookup table for storing results of
    // subproblems
    bool lookup[n + 1][m + 1];

    // initailze lookup table to false
    memset(lookup, false, sizeof(lookup));

    // empty pattern can match with empty string
    lookup[0][0] = true;

    // Only '*' can match with empty string
    for (int j = 1; j <= m; j++)
        if (pattern[j - 1] == '*')
            lookup[0][j] = lookup[0][j - 1];

    // fill the table in bottom-up fashion
    for (int i = 1; i <= n; i++) 
        for (int j = 1; j <= m; j++) 
            
            if (pattern[j - 1] == '*')
                lookup[i][j]
                    = lookup[i][j - 1] || lookup[i - 1][j];

            else if (pattern[j - 1] == '?'
                    || str[i - 1] == pattern[j - 1])
                lookup[i][j] = lookup[i - 1][j - 1];

            // If characters don't match
            else
                lookup[i][j] = false;
        
    

    return lookup[n][m];


int main()

    char pattern[] = "ajjajodojei*";
    char str[] = "ahdisahdisha";
    
    

    if (strmatch(str, pattern, strlen(str),
                strlen(pattern)))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;

    return 0;

【问题讨论】:

不,它们不相等。第一个做你想做的事,但不是出于你想的原因。第二个是不正确的。而bool lookup[n + 1][m + 1]; 是无效的 C++,因为 VLA 不是标准的一部分。 我提供的代码,即memset 工作正常,但是当我尝试使用bool loockup[n+1][m+1] 进行初始化时,我得到了错误的答案。所以我不认为第二个是不正确的,因为它给了我正确的答案。 对未定义的行为感到幸运与编写正确的代码不同。 @NathanPierson 你能澄清对memset() 的调用有什么问题吗?是指针,还是用于填充内存的值? OP 做错了什么并不是很明显。 @MarkRansom 我也认为对使用 VLA 的人大喊大叫是完全不公平和不合适的。我想这是一件好事,我没有,一点也不。回到手头的问题,它们并不常见:3 个主要的 C++ 编译器中有 1 个不支持它们。所以我确实认为有必要在有人使用它们时引起人们的注意,尤其是当他们似乎是初学者并且可能不知道这一点时。 【参考方案1】:

我不确定这种损坏的语法起源于何处,但这不是您在 C++ 中对对象进行零初始化的方式。这就是你的做法:

bool lookup = ; // note there's no false randomly thrown in there

还要注意上面不是数组,因为你的 VLA 在 C++ 中是无效的。

你的memset 调用也被破坏了,因为第二个参数不是bool,它是一个int,它被解释为unsigned char。只需阅读文档即可轻松解决这两个问题。

在 C++ 中正确定义数组的一些方法:

// nested vectors. This has the advantage of packing your values as bits instead of bytes.
std::vector<std::vector<bool>> arr;

// nested arrays stored as unique pointers. This has the advantage of automatic cleanup.
std::unique_ptr<std::unique_ptr<bool[]>[]> arr; 

// nested arrays stored as plain pointers. Just bad.
bool **arr;

// flat array of some kind. Use math to map your 2D index to a flat index and back.
std::vector<bool> arr;
std::unique_ptr<bool[]> arr;
bool *arr;

【讨论】:

很遗憾std::vector&lt;bool&gt; 坏了。 @bolov 它并没有坏到完全没用。我认为这里呈现的方式没有问题,尽管您肯定不会在上面使用memset 普遍的共识,即使在 C++ 专家之间也是避免std::vector&lt;bool&gt;。但是,是的,它们并非完全没用,您可以根据需要使用它们。 因为没有证据支持它们,这句话太多了。我会问你认为它有什么问题,尽管到处都在使用它,但我想我不想听到你试图一起逻辑一些东西。而你不是 memsetvector,这就是 clear() 的用途。 不要害怕问:) isocpp.org/blog/2012/11/…。 , ***.com/questions/17794569/… , ***.com/questions/6781985/… , gotw.ca/gotw/050.htm

以上是关于这两个操作在 C++ 中不是一回事吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++如何判断两个对象是不是是同一个对象?判断两个对象的地址可以吗?

eval() 和 new Function() 是一回事吗?

Java里有没有友元函数这回事

C++通过http协议操作hdfs

Verilog中,判断两个数是不是相等,一个数16位,一个数17位,16位的能自动补0吗?

Oracle 中的 SCHEMA 和 USER 是一回事吗?