名题百则source code:第七章---其他问题

本文探讨了在特定条件下对数组中的红、白、蓝三种颜色进行排序的有效算法,同时提供了一个能处理任意长度整数的加法和乘法的无限位数算术解决方案。

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

无耻的copy,然后号称原创~~~我稀饭

问题7.2 假设有一个数组,它有n个元素,每一个都不外乎是红、白、蓝3种颜色之一的代号,就用R、W、B代表。这些元素在数组中并没有依同样颜色排在一起的方式来排列,倾斜一个程序把这个元素排成所有蓝色在前,接着是白色,最后是红色的排列方式,不过在写程序时要满足下面的条件:

1. 不能用额外的内存,换句话说,只能在数组之内用互换的方式来完成。

2. 互换两个元素的动作要越少越好

3. 对于每一个元素而言,测试它是红、是白,还是蓝的工作每种颜色最多只能做一次测试。

在这个条件下,请写一个最快的程序。

#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>

using namespace std;

#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'

#define SWAP(x, y) { char temp; \
					temp = color[x]; \
					color[x] = color[y]; \
					color[y] = temp; \
					}

void dutch_flag(char *color)
{
	int white = 0;
	int blue = 0;
	int red = 0;

	while (red < strlen(color))
	{
		if (color[red] == RED)
			red++;
		else if (color[red] == WHITE)
		{
			SWAP(white, red);
			white++;
			red++;
		}
		else 
		{
			SWAP(blue, red);
			blue++;
			SWAP(white, red);
			white++;
			red++;
		}
	}
}

void main()
{
	char color[] = {'r', 'r', 'w', 'w', 'b', 'b', 'b', '\0'};
	const int size = sizeof color / sizeof *color;

	dutch_flag(color);
	for (int i = 0; i < size; i++)
		cout << color[i] << " ";
	cout << endl;
}

可惜啊,可惜,上面这个代码居然存在bug。。。

下面这组用例立马挂掉上面的程序:char color[] = {'r', 'b', 'w', '\0'};

正确的做法原理如下图所示:


正确的代码如下:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>

using namespace std;

#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'

#define SWAP(x, y) { char temp; \
					temp = color[x]; \
					color[x] = color[y]; \
					color[y] = temp; \
					}

void dutch_flag(char *color)
{
	int white = 0;
	int blue = 0;
	int red = strlen(color) - 1;

	while (white <= red)
	{
		if (color[white] == WHITE)
			white++;
		else if (color[white] == BLUE)
		{
			SWAP(white, blue);
			white++;
			blue++;
		}
		else 
		{
			SWAP(white, red);
			red--;
		}
	}
}

void main()
{
	char color[] = {'r', 'r', 'w', 'b', 'w', 'b', 'b', 'b', 'w', '\0'};
	const int size = sizeof color / sizeof *color;

	dutch_flag(color);
	for (int i = 0; i < size; i++)
		cout << color[i] << " ";
	cout << endl;
}

当用例为 char color[] = {'r', 'r', 'w', 'b', 'w', 'b', 'b', 'b', 'w', 'r', 'r', '\0'}; 时,不难发现存在多余的swap操作,可以做如下补充:

void dutch_flag(char *color)
{
	int white = 0;
	int blue = 0;
	int red = strlen(color) - 1;

	while (white <= red)
	{
		if (color[white] == WHITE)
			white++;
		else if (color[white] == BLUE)
		{
			SWAP(white, blue);
			white++;
			blue++;
		}
		else 
		{
			while (white < red && color[red] == RED)
				red--;
			SWAP(white, red);
			red--;
		}
	}
}

问题7.3  字符串列整数的转换

在平时课本中的atoi()函数范例,通常都不能查出溢出(overflow)的情况,或者是不理会这个情况而给出错误的结果,请修改这个atoi()程序,把转换后的结果用第二个参数返回来。例如,x_atoi(s,*t)就用t返回结果,而函数则指出OVERFLOW(大于最大整数值)、UNDERFLOW(小于最小整数值)、NO_ERROR(正常),为了方便起见,假设使用的机器是用2的补码存储整数,有没有办法查出机器是用1的补码还是2的补码?

题目比较简单

#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <limits.h>
#include <ctype.h>

using namespace std;

#define OVERFLOW 1
#define UNDERFLOW -1
#define NO_ERROR 0

int x_atoi(char *s, int *result)
{
	int digit_value;
	int i;

	*result = 0;
	for (i = 0; isdigit(s[i]); i++)
	{
		if (*result <= (INT_MAX - (digit_value = s[i] - '0')) / 10)
			*result = 10 * *result + digit_value;
		else
			return OVERFLOW;
	}
	return NO_ERROR;
}

void main()
{
	char *input = "123411111115";
	int result;
	int ret = x_atoi(input, &result);
	if (ret == NO_ERROR)
	{
		cout << "number = " << result << endl;
	}
	else if (ret == OVERFLOW)
	{
		cout << "over flow" << endl;
	}
}

问题7.5 无限位数算术

请写一个使用十进制运算,并且可以计算任意位数精确度的正整数加法和乘法的程序



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值