两个阵列:
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}
来测试班次等值。他们应该是,但我的计划说他们不是。
答案 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
}