字符编码(哈夫曼编码、贪心算法、priority_queue 的应用)---- 美团2016研发工程师编程题(二)

本文详细介绍了如何使用哈夫曼编码和贪心算法解决美团2016年研发工程师编程题。尽管题目中提及可以使用priority_queue,但解题方法并不限于此,还可以利用deque来实现。文章通过输入描述、输出描述及实例,清晰地展示了问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[编程题] 字符编码
请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。

输入描述:
每组数据一行,为待编码的字符串。保证字符串长度小于等于1000。


输出描述:
一行输出最短的编码后长度。

输入例子:
MT-TECH-TEAM

输出例子:
33
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <functional>

using namespace::std;

int main() {
	string input;

	while (cin >> input) {
		priority_queue<int, vector<int>, greater<int>> q;
		std::stable_sort(input.begin(), input.end());
		int count = 0;
		for (int i = 0; i < input.size(); ) {
			int j = i;
			while (j < input.size() && input[i] == input[j]) 
				++j;
			q.push(j - i);
			i = j;
			++count;
		}

		int result = 0;
		for (int i = 0; i < count - 1; ++i) {
			int first = q.top();
			q.pop();
			int second = q.top();
			q.pop();
            q.push( first + second ) ;
			result += first + second;
		}

		cout << result << endl;
	}
	return 0;
}



#include<iostream>
#include<queue>
#include<algorithm>
#include<string.h>
#define MAX 1000
using namespace std;
int main()
{
    char newString[MAX] = {0};
   while(cin>>newString)
    {
        int i, j;
        int countNum = 0;     //统计不同字符个数
        int sum = 0;              //记录编码后的长度
        int first = 0, second = 0;      //分别记录队列的最小两个值
        int len = strlen(newString);
        priority_queue <int, vector<int>, greater<int> > huffmanQueue;   //定义小值优先级高的队列
         sort(&newString[0], &newString[len]);
     
         for(i = 0; i < len; )
         {
                 j = i;
                 while((j < len)&&(newString[j] == newString[i]))   
                {
                      j++;
                }
               huffmanQueue.push(j - i);   //将字符newString[i]的个数压入队列
                i = j;
               countNum++;
        }
        for(i = 0; i < countNum - 1; i++)  //霍夫曼编码步骤
        {
              first = huffmanQueue.top();
              huffmanQueue.pop();
              second = huffmanQueue.top();
              huffmanQueue.pop();
              huffmanQueue.push(first + second);  
              sum += first + second;
        }
        cout<<sum<<endl;
    }//while
    return 0;
}

第二次做:

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <functional>

using namespace::std;

bool cmp(pair<char, int> first, pair<char, int> next) {
	return first.second < next.second;
}

int main() {
	string input;

	while (cin >> input) {
		if (input.empty() == true) continue;

		vector<pair<char, int>> vec;
		for (int i = 0; i < input.size(); ++i) {
			vec.push_back(make_pair(input[i], 1));
			for (int j = 0; j < vec.size() - 1; ++j) {
				if (vec[j].first == input[i]) {
					++vec[j].second;
					vec.pop_back();
					break;
				}
			}
		}

		stable_sort(vec.begin(), vec.end(), cmp);

		priority_queue<int, vector<int>, std::greater<int>> q;
		for (int i = 0; i < vec.size(); ++i) {
			q.push(vec[i].second);
		}

		int result = 0;
		while (q.size() >= 2) {
			int first = q.top();
			q.pop();
			int next = q.top();
			q.pop();
			q.push(first + next);
			result += first + next;
		}

		cout << result << endl;
	}

	return 0;
}

也不是必须要用优先级队列(priority_queue)来做,这道题完全可以用deque来做:

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <functional>

using namespace::std;

bool cmp(int first, int next) {
	return first < next;
}

int main() {
	string input;

	while (cin >> input) {
		if (input.empty() == true) continue;

		deque<pair<char, int>> vec;
		for (int i = 0; i < input.size(); ++i) {
			vec.push_back(make_pair(input[i], 1));
			for (int j = 0; j < vec.size() - 1; ++j) {
				if (vec[j].first == input[i]) {
					++vec[j].second;
					vec.pop_back();
					break;
				}
			}
		}
		deque<int> dq;
		for (int i = 0; i < vec.size(); ++i) {
			dq.push_back(vec[i].second);
		}
		stable_sort(dq.begin(), dq.end(), cmp);
		
		int result = 0;
		while (dq.size() >= 2) {
			int first = dq.front();
			dq.pop_front();
			int next = dq.front();
			dq.pop_front();
			dq.push_back(first + next);
			stable_sort(dq.begin(), dq.end(), cmp);
			result += first + next;
		}

		cout << result << endl;
	}

	return 0;
}


第四次做:

#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <algorithm>

using namespace::std ;

bool cmp( int first, int next ) {
    return first < next ;
}

int main() {
    string input ;
    
    while ( cin >> input ) {
        if ( input.empty() == true ) continue ;
        
        map<char, int> m ;
        for ( int i = 0; i < input.size(); ++ i ) {
            ++ m[input[i]] ;
        }
        
        deque<int> dq ;
        for ( map<char, int>::iterator iter = m.begin(); iter != m.end(); ++ iter ) {
            dq.push_back( ( *iter ).second ) ;
        }
        
        stable_sort( dq.begin(), dq.end(), cmp ) ;
        
        int result = 0 ;
        while ( dq.size() > 1 ) {
            int first = dq.front() ;
            dq.pop_front() ;
            int next = dq.front() ;
            dq.pop_front() ;
            result += first + next ;
            dq.push_back( first + next ) ;
            stable_sort( dq.begin(), dq.end(), cmp ) ;
        }
        
        cout << result << endl ;
    }
    
    return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值