Cracking The Coding Interview 3rd -- 1.5*

本文介绍了一种基本的字符串压缩方法,通过统计字符重复次数来进行压缩。提供了三种不同的实现方案:逐字符扫描并计数、利用ASCII码值作为索引进行计数及使用字符串缓冲区提高效率。同时展示了不同输入下各种压缩方法的效果。

Implement a method to perform basic string compression using the counts of repeated characters. For example, the string "aabcccccaaa" would become a2b1c5a3. If the "compressed" string would not become smaller than the original string, your method should return the original string.


Analysis: This problem only asks for compressing in such way that we don't need to worry about combining "a2" and "a3" together. As required, it would be pretty straight forward that we simply scan original string and create a new string, then compare. 


Solution 1:

Scan every character in string and count its occurrences.


Solution 2:

Further compression, combine "a2" and "a3" into "a5", as a result the order of characters will change. In this algorithm, we use an integer array of size 256 to store the counts of each character as discussed in previous questions.


Solution 3 ... 

According to book solution, string concatenation takes much longer time, as a result we should use stringbuffer (Java). I will post c++ version later.


 Header file

#ifndef __QUESTION_1_5_H_CHONG__
#define __QUESTION_1_5_H_CHONG__

#include <string>

using namespace std;

class Question1_5 {
public:
  string stringCompression(string target);
  string stringCompression_2(string target);
  string stringCompression_3(string target);
  int run();
};
#endif // __QUESTION_1_5_H_CHONG__


Source file

#include "stdafx.h"
#include "Question1_5.h"
#include <iostream>

using namespace std;

string Question1_5::stringCompression(string target)
{
  if (target.size()==0) {
    return target;
  }

  string res = "";  // new string storing results
  char c = target[0];   // previous different character
  int cnt = 1;    // counts on each character
  for (int i=1; i<target.size(); ++i) {
    if (target[i]==c) {
      cnt++;
    }
    else {
      res += c;
      res += char(cnt+'0');
      cnt = 1;
      c = target[i];
    }
  }
  // The loop always misses the last character in string, so we add them back
  res += c;
  res += char(cnt+'0');

  if (res.size()<target.size()) {
    return res;
  }
  else 
    return target;
}

// use ASCII 256 array to storage counts on each character
string Question1_5::stringCompression_2(string target)
{
  if (target.size()==0) {
    return target;
  }

  string res = "";
  int counts[256] = {0};
  for (int i=0; i<target.size(); ++i) {
    counts[int(target[i])]++;
  }
  for (int i=0; i<256; ++i) {
    if (counts[i]!=0) {
      res += char(i);
      res += char(counts[i]+'0');
    }
  }

  if (res.size()<target.size()) {
    return res;
  }
  else return target;
}

string Question1_5::stringCompression_3(string target) 
{
	...
}

int Question1_5::run() 
{
  // assume there's no spaces in string
  string input[] = {"abcdabcd", "aaabbbcccddddaaabbbcccdddd"};
  for (int i=0; i<2; ++i) {
    cout << input[i] << " after compression_1 is " << stringCompression(input[i]) 
      << " after compression_2 is " << stringCompression_2(input[i]) << endl;
  }

  return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值