110308 Fmt


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

using namespace std;

enum CharType_t
{
	SPACE,
	NEWLINE,
	NORMAL
};

struct StrInfo
{
	StrInfo(char* str, int len, CharType_t charType) : 
		m_len(len), m_charType(charType)
	{
		m_str = new string(str);
	}

	StrInfo(string* str) : m_str(str)
	{
	}

	~StrInfo()
	{
		if (m_str)
			delete m_str;
	}

	string* Detach()
	{
		string* tmp = m_str;
		m_str = NULL;
		return tmp;
	}

	void Change(char* str, int len, CharType_t charType)
	{
		if (m_str)
			delete m_str;
		m_str = new string(str);
		m_len = len;
		m_charType = charType;
	}

	string* m_str;
	int m_len;
	CharType_t m_charType;
};

typedef vector<StrInfo*> StringCol;

#define MAX_CHARS 72
#define MAX_BUF 4096

static void ClearStringCol(StringCol& strCol)
{
	StringCol::iterator iter = strCol.begin();
	while(iter != strCol.end())
	{
		delete (*iter);
		++iter;
	}
}

static void AddStrsFromLineToStringCol(StringCol& strCol, char* line)
{
	if (!line)
		return;

	int len = strlen(line);

	int i = 0, j;
	char originalEnd;
	while(i < len)
	{
		switch(line[i])
		{
		case ' ':
			strCol.push_back(new StrInfo(" ", 1, SPACE));
			++i;
			break;
		case '\n':
			strCol.push_back(new StrInfo("\n", 1, NEWLINE));
			++i;
			break;
		default:
			j = i + 1;
			while((line[j] != ' ') && (line[j] != '\n') && (line[j] != '\0'))
				++j;
			originalEnd = line[j];
			line[j] = '\0';
			strCol.push_back(new StrInfo(line + i, j - i, NORMAL));
			line[j] = originalEnd;
			i = j;
			break;
		}
	}
}

static void StartNewLine(int& curCharsCntInLine, bool& curLineIsBlank, StringCol& strCol)
{
	// Delete the spaces in the end of the line first.
	int last = strCol.size() - 1;
	while(last >= 0)
	{
		if ((*(strCol[last]->m_str))[0] == ' ')
		{
			delete strCol[last];
			strCol.pop_back();
			--last;
		}
		else
			break;
	}

	// Now we can add the new line and reset the count and flag.
	strCol.push_back(new StrInfo(new string("\n")));
	curCharsCntInLine = 0;
	curLineIsBlank = true;
}

static void AddStrToFormattedStrCol(
	StringCol::iterator& iter, const StringCol::iterator& end, StringCol& formattedStrCol,
	int& curCharsCntInLine, bool& curLineIsBlank)
{
	StrInfo& strInfo = *(*iter);
	switch(strInfo.m_charType)
	{
	case NORMAL:
		curCharsCntInLine += strInfo.m_len;
		curLineIsBlank = false;
		formattedStrCol.push_back(new StrInfo(strInfo.Detach()));
		++iter;
		break;

	case SPACE:
		curCharsCntInLine += strInfo.m_len;
		if (curCharsCntInLine >= MAX_CHARS)
		{
			StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
		}
		else
		{
			if ((iter + 1) != end)
			{
				StrInfo& nextStrInfo = *(*(iter + 1));
				if ((curCharsCntInLine + nextStrInfo.m_len) > MAX_CHARS)
					StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol); // Ignore this SPACE
				else
					formattedStrCol.push_back(new StrInfo(strInfo.Detach()));
			}
		}
		++iter;
		break;

	default: // case NEWLINE
		if ((iter + 1) == end)
		{
			StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
			++iter;
		}
		else if (curLineIsBlank || 
			((*(iter+1))->m_charType == NEWLINE) || 
			((*(iter+1))->m_charType == SPACE))
		{
			StartNewLine(curCharsCntInLine, curLineIsBlank, formattedStrCol);
			++iter;
		}
		else
			(*iter)->Change(" ", 1, SPACE); // Ignore this NEWLINE and change it to SPACE

		break;
	}
}

static void FormatStrCol(StringCol& originalStrCol, StringCol& formattedStrCol)
{
	StringCol::iterator iter = originalStrCol.begin();
	int curCharsCntInLine = 0;
	bool curLineIsBlank = true;

	while(iter != originalStrCol.end())
		AddStrToFormattedStrCol(iter, originalStrCol.end(), formattedStrCol, curCharsCntInLine, curLineIsBlank);
}

static void OutputStrCol(const StringCol& strCol)
{
	StringCol::const_iterator iter = strCol.begin();
	while(iter != strCol.end())
	{
		cout << (*((*iter)->m_str));
		++iter;
	}
}

static void GetInputs(StringCol& strCol)
{
	char buf[MAX_BUF];
	while(fgets(buf, MAX_BUF, stdin))
	{
		if (buf[0] == '\0')
			return;
		AddStrsFromLineToStringCol(strCol, buf);
	}
}

static void DoTest()
{
	StringCol originalStrCol, formattedStrCol;
	GetInputs(originalStrCol);
	FormatStrCol(originalStrCol, formattedStrCol);
	OutputStrCol(formattedStrCol);
	ClearStringCol(originalStrCol);
	ClearStringCol(formattedStrCol);
}

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值