程序员面试金典: 9.11 排序与查找 11.1编写一个方法,对字符串数组进行排序,将所有变位词排在相邻的位置。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include  <string>
#include <map>

using namespace std;

/*
问题:编写一个方法,对字符串数组进行排序,将所有变位词排在相邻的位置。
分析:首先变位词表示两个词可以通过变化变成另一个词,一个办法就是统计所有字符出现次数,若两个字符串对应
      字符出现次数都相等,表示是变位词。
	  解法:先对字符串数组按照普通排序(sort),然后遍历字符串数组,对每个字符串排序,如果该字符串出现在<字符串,字符串数组>映射中
	        就加入当前字符串
			时间复杂度:排序O(N*LogN) + 遍历每个字符串再排序O(N*N*LogN),应该是O(N^2*logN)

输入:
5(字符串元素个数)
abc abd bac cad cab
输出:
abc bac cab abd cad

关键:
书上解法:
1、由于变位词之间没有顺序,因此可以修改通用排序算法中字符串比较规则,先将两个字符串各自排序,然后再比较
2、或者直接遍历字符串数组,对每个字符串排序,如果该字符串出现在<字符串,字符串数组>映射中
	        就加入当前字符串
*/

//这个函数里面发生中断了,有bug
bool compare(string str1 , string str2)
{
	/*
	if(str1.empty() && str2.empty())
	{
		return true;
	}
	else if(str1.empty())
	{
		return true;
	}
	else if(str2.empty())
	{
		return false;
	}
	*/
	string tempStr1 = str1;
	string tempStr2 = str2;
	sort(tempStr1.begin() , tempStr1.end());
	sort(tempStr2.end() , tempStr2.end());
	//然后比较两个字符串,这里strcmp返回正数: str1 > str2 ,str1<str2返回负数
	int result = strcmp(tempStr1.c_str() , tempStr2.c_str() );
	bool flag = result < 0  ? true : false;
	return flag;
}

vector<string> stringSort(vector<string>& inputStrings)
{
	sort(inputStrings.begin() , inputStrings.end() , compare);
	return inputStrings;
}

void print(vector<string>& strings)
{
	int size = strings.size();
	for(int i = 0 ; i < size ; i++)
	{
		cout << strings.at(i) << " ";
	}
	cout << endl;
}

//变位词排序2:
map<string , vector<string> > stringSort2(vector<string>& inputStrings)
 {
	 //先正常排序,不需要正常排序,题目没有说明变位词之间还有顺序
	 //sort(inputStrings.begin() , inputStrings.end());
	 map<string , vector<string> > strToList;
	 int size = inputStrings.size();
	 string str;
	 string sortStr;
	 for(int i = 0 ; i < size ; i++)
	 {
		 sortStr = str = inputStrings.at(i);
		 sort(sortStr.begin() , sortStr.end());
		 map<string , vector<string> >::iterator it = strToList.find(sortStr);
		 //如果该变位词字符串出现过
		 if(it != strToList.end() )
		 {
			 it->second.push_back(str);
		 }
		 else
		 {
			 vector<string> strings;
			 strings.push_back(str);
			 strToList.insert(pair<string , vector<string> >(sortStr , strings));
		 }
	 }
	 return strToList;
 }

void print(map<string , vector<string> >& strToList)
{
	vector<string> strings;
	int size;
	for(map<string , vector<string> >::iterator it = strToList.begin() ; it != strToList.end() ; it++)
	{
		strings = it->second;
		size = strings.size();
		for(int i = 0 ; i < size ; i++)
		{
			cout << strings.at(i) << " ";
		}
	}
	cout << endl;
}

void process()
{
	int n;
	vector<string> strings;
	string value;
	map<string , vector<string> > strToList;
	while(cin >> n)
	{
		strings.clear();
		strToList.clear();
		for(int i = 0 ; i < n ; i++)
		{
			cin >> value;
			strings.push_back(value);
		}
		strToList = stringSort2(strings);
		print(strToList);
		/*
		strings = stringSort(strings);
		print(strings);
		*/
	}
}

int main(int argc, char* argv[])
{
	process();
	getchar();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值