我试图在地图的帮助下解决这个问题。我是Map的新手,但我不确定我的地图逻辑是否可以扩展为字符串?
`void findUniqueRows(int M[R][C])
map<int,string> m;
for(int i=0;i<R;i++)
{
string str="";
for(int j=0;j<C;j++)
str+=M[i][j];
m.insert(i,str);
`}
for (std::map<int,string>::iterator it=m.begin(); it!=m.end(); ++it)
std::cout << it->first << " => " << it->second << '\n';
}“
基本上我正在尝试使用int创建map作为行no和string作为该行的所有数组元素的串联。 现在对于下一行,同样的事情发生但如果当前字符串与地图中的现有字符串匹配,则不会插入。因此我的地图将包含唯一的行。 我是对的吗?
答案 0 :(得分:1)
不,你的方法不正确。 std::map
不关心它存储的键/值对的第二项内容。它只查看第一项。如果它已存在于地图中,则具有相同键的后续insert()
将不会更改地图。所以在:
for (int j=0; j < C; j++) {
str += M[i][j];
m.insert(i, str);
}
当j == 0
时,对insert()
的调用将成功,但该循环中的任何后续调用都不会执行任何操作。
使用地图根本无法解决这个问题,除非您的输入数组很大并且您需要一个比O(R²)快的算法。我会保持简单并使用以下方法:
for (int i = 0; i < R; i++) {
bool duplicate = false;
// Check if we have seen this row before
for (int j = 0; j < i - 1; j++) {
// Are the contents of row i equal to those of row j?
if (memcmp(M[i], M[j], C * sizeof **M)) {
duplicate = true;
break;
}
}
// If not, print it
if (!duplicate) {
for (int k = 0; k < C; k++)
std::cout << M[i][k] << " ";
std::cout << "\n";
}
}
如果您确实想要使用类似地图的方法,则应使用std::set
代替。这是一个可能的例子:
// Function to compare two rows
auto compare_row = [](int *a, int *b){
return memcmp(a, b, C * sizeof *a) < 0;
};
// A set that stores pointers to rows, using the above comparison function
std::set<int *, decltype(compare_row)> myset(compare_row);
// Insert all rows into the set
for (int i = 0; i < R; i++)
myset.insert(M[i]);
// Print contents of the set
for (auto &&row: myset) {
for (int k = 0; k < C; k++)
std::cout << row[k] << " ";
std::cout << "\n";
}
上面的示例只存储指向原始数组的指针,因此它非常节省空间。请注意,该集合现在基于比较函数进行排序,因此结果不一定与输入数组的顺序相同。要保持相同的顺序,您需要检查insert()
调用的结果,并仅在插入成功时打印:
for (int i = 0; i < R; i++) {
if (myset.insert(M[i]).second) {
// print row i
}
}
答案 1 :(得分:0)
使用std::map
的方法可以看作示范程序中显示的内容。
#include <iostream>
#include <algorithm>
#include <map>
#include <iterator>
int main()
{
const size_t M = 5;
const size_t N = 6;
int a[M][N] =
{
{ 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0 },
{ 1, 1, 1, 1, 0, 0 },
{ 1, 1, 1, 1, 1, 0 },
{ 1, 1, 1, 1, 1, 1 }
};
auto comp = []( const int ( *a )[N], const int ( *b )[N] )
{
return std::lexicographical_compare(
std::begin( *a ), std::end( *a ),
std::begin( *b ), std::end( *b ) );
};
std::map<const int(*)[N], size_t, decltype( comp )> m( comp );
for ( const int ( *row )[N] = a; row != a + M; ++row )
{
++m[row];
}
for ( const auto &p : m )
{
if ( p.second == 1 )
{
std::cout << '['
<< std::distance( std::cbegin( a ), p.first )
<< "]: ";
for ( int x : *p.first ) std::cout << x << ' ';
std::cout << std::endl;
}
}
return 0;
}
它的输出是
[2]: 1 1 1 1 0 0
实际上,索引等于2的行是唯一的行。