我已经生成了一个10x10整数矩阵,通过二维数组,元素是随机生成的并且位于
1 <= z <= 5.
我需要一种有效的方法,将长度为3或更大的任何行或列(非对角线)的所有相邻“重复”(重复元素)设置为整数六(6)。为了清楚起见,遵循粗暴方法的来源。
for(row=0;row<10;row++)
{
for(col=0;col<10;col++)
{
board[row][col]=rand()%4+1; //filling matrix here
}
}
print_board(board, row, col);
printf("Switch: ROW COLUMN\n ");
scanf("%hu %hu", &x1, &y1);
printf("With: ROW COLUMN\n");
scanf("%hu %hu", &x2, &y2);
swap(board, x1, y1,x2, y2); //stdrd for loop no good b/c of
//below <-this->below
if(board[0][0]==board[0][1] && board[0][1]==board[0][2] && board[0][2]==board[0][3])
{
board[0][0]=6;
board[0][1]=6;
board[0][2]=6;
board[0][3]=6; // brute force would require many more to complete
}
我知道必须存在比列出所有排列更优雅的方法。如果您已经看到这个并回想起这项技术,我将非常感谢您的帮助。 C-Monster
答案 0 :(得分:2)
我不确定是否有更优雅的方式来实现它,我正在提供我现在所做的。
a[0][0]==a[0][1] && a[0][1] != a[0][2]
,则不需要比较[0] [1]和[0] [3-9],从比较a [0] [2]和[0]开始[3-] 9]。`
int main()
{
int board[10][10];
int row=0,col=0;
srand((unsigned int)(time(NULL)));
for (row=0;row<10;++row)
{
for(col=0;col<10;++col)
{
board[row][col] = rand()%5 + 1;
printf("%d ", board[row][col]);
}
printf("\n");
}
int count = 1;
int seek = 0;
for(row=0;row<10;++row)
{
for(col=1;col<8;++col) //compare at least 3 elements
{
for(seek=col+1;seek<10;)
{
if(board[row][col] == board[row][seek])
{
++count;
++seek;
}
else
{
col = seek-1;
break; //change the start element
}
}
if (count >= 3)
{
//print the found location
//printf("%d %d\n", row, seek-1);
int i;
for(i=seek-1;count>=1;--count)
board[row][i--] = 6;
}
count = 1;
}
}
//print the result
for (row=0;row<10;++row)
{
for(col=0;col<10;++col)
{
printf("%d ", board[row][col]);
}
printf("\n");
}
return 0;
}
`
答案 1 :(得分:1)
对于每一行,扫描列。读取一个元素,然后向前扫描列,直到到达最后一列,或者找到一个具有不同值的元素。如果跨度的长度大于或等于3,请返回并将所有元素设置为6.如果尚未到达最后一列,请从导致您停止的元素继续扫描。
答案 2 :(得分:1)
您的问题非常适合以SIMD方式进行,因为SIMD会并行比较连续数据的操作。这种方法的运行速度明显快于任何类型的普通C代码。
我假设您的board[][]
有int
类型。有一个例子可以在我的MinGW上正常工作。您需要为SSE2内在函数添加标头intrin.h
或emmintrin.h
。
您可以替换代码中的所有10
来调整board
的大小。
#include <emmintrin.h>
int main(){
int board[10][10];
int row, col;
for(row=0;row<10;row++){
for(col=0;col<10;col++){
board[row][col]=rand()%2+1; //filling matrix here
printf("%d ", board[row][col]);
}
printf("\n");
}
printf("\n");
for(row=0;row<10;row++){
col = 0;
while(col <= 10 - 4){
__m128i xmm0 = _mm_loadu_si128((__m128i*)&board[row][col]);
__m128i xmm1 = _mm_set1_epi32(board[row][col]);
__m128i xmm2;
__m128i xmm6 = _mm_set1_epi32(6);
__m128i xmmn = _mm_set1_epi32(-1);
unsigned long c;
int mask;
xmm0 = _mm_xor_si128(_mm_cmpeq_epi32( xmm0, xmm1 ), xmmn);
mask = _mm_movemask_epi8(xmm0);
if (!mask){
_mm_storeu_si128( (__m128i*)&board[row][col], xmm6 );
col += 4;
do{
if (col > 10 - 4) col = 10 - 4;
xmm0 = _mm_loadu_si128((__m128i*)&board[row][col]);
xmm2 = _mm_or_si128( _mm_cmpeq_epi8( xmm0, xmm1 ), _mm_cmpeq_epi8( xmm0, xmm6 ) );
xmm0 = _mm_xor_si128(xmm2, xmmn);
xmm0 = _mm_or_si128(_mm_slli_si128(xmm0, 4), xmm0);
xmm0 = _mm_or_si128(_mm_slli_si128(xmm0, 8), xmm0);
xmm2 = _mm_xor_si128(xmm0, xmmn);
_mm_maskmoveu_si128( _mm_set1_epi32(6), xmm2 , (char*)&board[row][col] );
mask = _mm_movemask_epi8(xmm0);
if (col == 10 - 4){
col++;
break;
}
c = __builtin_ctz(mask);/* In MSVC: _BitScanForward(mask, &c); */
c >>= 2;
col += c;
}while(mask);
}else{
col += __builtin_ctz(mask) >> 2;
}
}
}
for(row=0;row<10;row++){
for(col=0;col<10;col++){
printf("%d ", board[row][col]);
}
printf("\n");
}
return 1;
}