UVa Problem 10010 Where’s Waldorf?(寻找单词)

寻找Waldorf算法解析
本文介绍了一个用于在字母矩阵中搜索特定单词的算法。该算法通过预先判定可能的方向和长度,有效地减少了不必要的比较,提高了搜索效率。文章提供了完整的C++实现代码,包括如何遍历矩阵、判定匹配方向及进行匹配尝试。
// Where’s Waldorf? (序找单词) // PC/UVa IDs: 110302/10010, Popularity: B, Success rate: average Level: 2 // Verdict: Accepted // Submission Date: 2011-05-22 // UVa Run Time: 0.016s // // 版权所有(C)2011,邱秋。metaphysis # yeah dot net // // 使用数组来表示方向,在比较之前先判定长度,避免不可能的比较。 #include <iostream> #include <vector> #include <cstring> using namespace std; int abs(int a) { return a >= 0 ? a : (-1) * a; } bool equal(char a, char b) { return (a == b) || (abs(a - b) == 32); } void find(vector < string > & matrix, int nlines, int nrows, string word) { int length = word.length(); int bounds[8][2] = { {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1} }; int test[8]; for (int i = 0; i < nlines; i++) for (int j = 0; j < nrows; j++) if (equal(matrix[i][j], word[0])) { memset(test, 0, sizeof(test)); // 判定八个方向是否需要尝试匹配,若值为 1 表示需要尝试。 if ((j + 1) >= length) test[0] = 1; if ((j + 1) >= length && (i + 1) >= length) test[1] = 1; if ((i + 1) >= length) test[2] = 1; if ((nrows - j) >= length && (i + 1) >= length) test[3] = 1; if ((nrows - j) >= length) test[4] = 1; if ((nrows - j) >= length && (nlines - i) >= length) test[5] = 1; if ((nlines - i) >= length) test[6] = 1; if ((j + 1) >= length && (nlines - i) >= length) test[7] = 1; // 尝试匹配。 for (int m = 0; m < 8; m++) if (test[m]) { int directx = bounds[m][0]; int directy = bounds[m][1]; int posx = j; int posy = i; int start = 0; bool matched = true; while (start < length) if (equal(matrix[posy][posx], word[start])) { start++; posx += directx; posy += directy; } else { matched = false; break; } // 判断是否符合。 if (matched) { cout << (i + 1) << " " << (j + 1) << endl; return; } } } } int main(int ac, char *av[]) { vector < string > matrix; // 字母矩阵。 int cases; // 测试数据组数。 int current = 0; // 当前数据组数。 int nlines; // 矩阵行数。 int nrows; // 矩阵列数。 int nwords; // 每组数据待查找的单词个数。 string line; cin >> cases; while (current < cases) { cin >> nlines >> nrows; cin.ignore(); // 清空向量数组。 matrix.clear(); for (int i = 0; i < nlines; i++) { getline(cin, line); matrix.push_back(line); } cin >> nwords; cin.ignore(); for (int i = 0; i < nwords; i++) { getline(cin, line); find(matrix, nlines, nrows, line); } current++; if (current < cases) cout << '\n'; } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值