创建一个布尔函数,确定两个数组是否相等

时间:2013-02-01 01:15:28

标签: c++ function boolean dynamic-arrays boolean-expression

两个阵列:

a[] = {1 2 3 4}
b[] = {3 4 1 2}

底部数组只是向右移动到两个位置的顶部数组。如果顶部数组可以右移以创建底部数组,我们将它们称为移位等效。

这是我尝试创建一个函数(我需要使用一个布尔函数)来确定两个数组是否是“等效移位”:

#include <iostream>
using namespace std;

bool equivalent(int a[], int b[], int size) {

    int value; // if 1 returns as truth
    int k; // counter to compare both arrays

    for (int j = 0; j <= size; j++) {
        for (int i = 0; i <= size; i++) {
            a[i] = a[i + j];
        }
    }

    for (k = 0; k <= size; k++) {
        if (a[k] != b[k]) {
            value = 0;
        } else value = 1;
    }

    return (value == 1);
}

int main() {
    int n;
    cout << "Please input a size " << endl;
    cin >> n;

    int *mtrx = new int[n];
    int *mtrx1 = new int[n];
    int x;
    for (x = 0; x < n; x++) {
        cout << "Please make entries for the first array: " << endl;
        cin >> mtrx[x];
    }
    x = 0;
    for (x = 0; x < n; x++) {
        cout << "Please make entries for the 2nd array: " << endl;
        cin >> mtrx1[x];
    }

    bool answr = equivalent(mtrx, mtrx1, n = n - 1);

    if (answr) {
        cout << "They are shift equivalent." << endl;
    } else {
        cout << "They are not shift equivalent." << endl;
    }

    delete[] mtrx;
    delete[] mtrx1;

    system("PAUSE");
    return 0;
}

当我执行我的程序时,我使用array1 = {1 2 3}array2 = {3 1 2}来测试班次等值。他们应该是,但我的计划说他们不是。

2 个答案:

答案 0 :(得分:4)

我在您的代码中看到的一个问题是您访问数组之外​​的内存。如果你添加两个索引,你必须确保它们“环绕”,如果你想对你的数组进行循环处理。这可以用模数来完成。而不是

a[i + j]

你应该写

a[(i + j) % size]

我将你的算法分成两部分:首先,编写一个函数,测试a是否等于b,移位为shift。然后,在第二个函数(最终equivalent函数)中,测试shift的所有可能值。

bool equivalentFixed(int a[], int b[], int size, int shift) {
    for (int i = 0; i < size; ++i) {
        if (a[i] != a[(i + shift) % size])
            return false;
    }
    return true;
}

bool equivalent(int a[], int b[], int size) {
    for (int shift = 0; shift < size; ++shift) {
        if (equivalentFixed(a, b, size, shift))
            return true;
    }
    return false;
}

如果你仔细观察,如果数组是等价的,你看不到任何局部变量来保存(存储)该值。实际上,您的代码也存在问题,因为对于您比较的每个条目,您始终使用新状态覆盖旧状态。因此,如果在扫描数组期间比较失败,但最后一个条目比较相等,则返回“是,它们相等”,因为您已覆盖状态。

现在看一下我的equivalent实现。如果阵列比较相等,我会扫描不同的偏移量(shift)。让我们关注这个函数,而不是如何在另一个函数中进行比较。重点是:如果任何移位他们比较相等,我们必须返回true,而不是最后,而不是所有

解决这个问题的想法是在找到解决方案时打破循环(停止)。您甚至可以返回整个函数,因为您知道完整的返回值,即true

如果没有可能的转变,则比较成立,我们没有发现任何可能的转变,因此它们不是“等效转移”。

我使用了一种非常类似的方法来实现具有固定移位(equivalentFixed)的两个数组的比较。你能解释一下这是怎么做到的吗?

答案 1 :(得分:0)

在这里你得到i+j>size

a[i]=a[i+j]; 

这里只是一个简单的变体,只能在一个函数中使整体:(这是一个罕见的情况,当使用dynosaur goto很好 - 离开内部循环,不引入新的时间变量)

#include <iostream>
using namespace std;

bool equivalent(int a[], int b[], int size) 
{
    for (int j = 0; j < size; j++) 
    {
        for (int i = 0; i < size; i++) 
        {
            if (a[i] != b[(i + j)%size]) goto next_shift;
        }
        return true;
        next_shift: ;
    }
    return false;
}

int main() {
    int n;
    cout << "Please input a size " << endl;
    cin >> n;

    int *mtrx = new int[n];
    int *mtrx1 = new int[n];
    int x;
    for (x = 0; x < n; x++) {
        cout << "Please make entries for the first array: " << endl;
        cin >> mtrx[x];
    }
    x = 0;
    for (x = 0; x < n; x++) {
        cout << "Please make entries for the 2nd array: " << endl;
        cin >> mtrx1[x];
    }

    bool answr = equivalent(mtrx, mtrx1, n );

    if (answr) {
        cout << "They are shift equivalent." << endl;
    } else {
        cout << "They are not shift equivalent." << endl;
    }

    delete[] mtrx;
    delete[] mtrx1;

    system("PAUSE");
    return 0;
}

编辑:来自:C ++编程语言。第三版。 Bjarne Stroustrup

  

6.3.4转到[expr.goto]   C ++拥有臭名昭着的词:

goto identifier ;
identifier : statement
  

在一般高级编程中几乎没有什么用途

...

  

普通代码中goto的少数合理用法之一就是破解   从嵌套循环或switch语句中出来(break突然出现   只有最里面的封闭循环或switchstatement)。

     

例如:

voidf ()
{
int i ;
int j ;
for (i = 0 ; i <n ; i ++)
for (j = 0 ; j <m ; j ++) i f (nm [i ][j ] == a ) goto found ;
// not found
// ...
found :
// nm[i][j] == a
}