首先,简单总结一下问题:
我们有两列,其中包含许多不同的标记。
每个令牌出现偶数次。目标是交换行,以便最终每个标记在每列中出现相同的次数。
首先我浏览所有数据,计算每个标记出现的次数。
然后对于每个标记,我遍历每一列并检查是否出现了该特定标记。如果我在该列中遇到超过 n/2 个标记,则它会被交换。
重复整个过程,直到不再需要交换为止。
我不确定两件事:a) 一般而言,总会有解决问题的方法(我几乎可以肯定一定是这种情况......)? B)我能确定迭代总是会停止吗? IE。来回交换东西不会卡住吗?
无论如何,这里有一些代码可以做到这一点。请注意,没有检查输入是否正确等。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class my_pair
{
private:
int m_x,m_y;
public:
my_pair( int x, int y ) : m_x( x ), m_y( y ) {}
void swap()
{
int tmp = m_x;
m_x = m_y;
m_y = tmp;
}
int x()
{
return m_x;
}
int y()
{
return m_y;
}
};
int main()
{
// Generate some input:
// I'm assuming that the tokens in the columns are
// in the form 0,1,2 etc such that the tokens
// themselves can be interpreted as an index of an array.
// I think there is no loss of generality here, as it can
// be considered a re-labeling...
vector<my_pair> pair_vector;
pair_vector.push_back( my_pair( 0,1 ) );
pair_vector.push_back( my_pair( 1,1 ) );
pair_vector.push_back( my_pair( 2,2 ) );
pair_vector.push_back( my_pair( 2,1 ) );
pair_vector.push_back( my_pair( 2,0 ) );
pair_vector.push_back( my_pair( 2,1 ) );
pair_vector.push_back( my_pair( 2,1 ) );
pair_vector.push_back( my_pair( 2,2 ) );
cout << "Start vector:" << endl;
for( auto p : pair_vector )
cout << p.x() << ' ' << p.y() << endl;
// 1: Count number of occurrences of each token.
// Here the assumption on the tokens is used:
vector<int> num_tokens;
for( auto& p : pair_vector )
{
if( p.x()+1 > num_tokens.size() )
num_tokens.resize( p.x()+1 );
num_tokens[p.x()]++;
if( p.y()+1 > num_tokens.size() )
num_tokens.resize( p.y()+1 );
num_tokens[p.y()]++;
}
// 2. Now I iterate through the columns for each token
// and swap each token
// that appears more often than n/2 times in that column,
// where n is the number of appearances of each token:
bool swap_was_performed = true;
while( swap_was_performed )
{
int token = 0;
swap_was_performed = false;
for( auto& n : num_tokens ) // n is the number (or frequency) of tokens
{
int x_ctr = 0;
int y_ctr = 0;
// Iterating through the input columns:
for( auto& p : pair_vector )
{
if( p.x()==token ) // x-values (i.e. the first column)
{
x_ctr++;
if( x_ctr>n/2 )
{
p.swap();
swap_was_performed = true;
}
}
}
for( auto& p : pair_vector )
{
if( p.y()==token ) // y-values...
{
y_ctr++;
if( y_ctr>n/2 )
{
p.swap();
swap_was_performed = true;
}
}
}
token++;
}
}
cout << "After re-arranging:" << endl;
for( auto p : pair_vector )
cout << p.x() << ' ' << p.y() << endl;
}