渣基础:比照Hawstein学Cracking the coding interview(1)

《C++ Primer 第五版》书实在是太长,太厚了。总是看了十几页就看累了,坚持不了多久,想了想还是别勉强自己,决定把它当工具书查看,或者积累足够的C++经验后再翻阅一遍。


目前的打算是结合一本叫《Craking the coding interview》里的例子来学,选这个的原因是 fanfanK http://blog.csdn.net/fanfank?viewmode=contents 的推荐,同时这本书又有hawstein   http://hawstein.com/posts/ctci-solutions-contents.html 提供很好的解答环境,打算每天做3题。


10.8


作者:Hawstein
出处:http://hawstein.com/posts/1.1.html
声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处。


Q1.1:       http://hawstein.com/posts/1.1.html

实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)

方法一采用了一个bool数组来记录是否出现过,方法的特点主要是结合Ascii码可以转换为数字,对应记录到数组中。

方法二把数组记录变为了一个长度为8的int 数组a,然后进行位运算,8*4*8=256,

看这个方法二的时候 顺便学习了下《C++ Primer 第五版》里的4.8 位运算符的部分。其中P137中写道:常见的错误是把位运算符和逻辑运算符搞混了。这也的确是我犯过的错误,比如位或| 和逻辑或|| 搞混过。

P126:“关系运算符作用于算数类型或指针类型,逻辑运算符作用于任意能转换成布尔值的类型。逻辑运算符和关系运算符的返回值都是布尔类型”


个人感想:用bool数组和位来记录一些0,1数据,的确很节省,顺便复习了下运算符。


Q1.2 http://hawstein.com/posts/1.2.html

写代码翻转一个C风格的字符串。(C风格的意思是"abcd"需要用5个字符来表示,包含末尾的 结束字符)

方法一用的是用两个指针去分别指头和尾,然后用逐个交换,其中的交换函数是这么写的:

void swap(char &a, char &b)
{
	a=a^b;
	b=a^b;
	a=a^b;
}

用的是引用传递,同时类似的交换方法有:

void swap(int &a, int &b)
{
	b=a-b;
	a=a-b;
	b=a+b;
}

这里会有一个小的bug,就是:如果swap这个函数里两个形参引用的是同一个变量,那么这两种方法都会出问题,存在这种情况的时候,还是用临时变量比较好。

这里顺便完成了Q19.1:写一个函数交换两个数,不能使用临时变量。 http://hawstein.com/posts/19.1html

方法二就是常规思路了,直接用int n=strlen(s) 来获取字符串长度,然后逐个交换即可。


个人感想:字符串用指针来处理,交换两个数时,可能存在bug。


Q1.3:

设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。

方法一:就单纯遍历每个元素,访问一个就把字符串结尾的元素中相同的元素去掉(可以置0 或者 ‘\0'),时间复杂度为O(n*n)

void removeDuplicate(char s[])
{
    int len = strlen(s);
    if(len < 2) return;
    int p = 0;
    for(int i=0; i < len; ++i)
    {
        if(s[i] != '\0')
        {
            s[p++] = s[i];
            for(int j=i+1; j < len; ++j)
                if(s[j]==s[i])
                    s[j] = '\0';
        }
    }
    s[p] = '\0';
}

也有另外一种方法是O(kn)的,就是看0~tail之间有没有这个字符,没的话就s[tail++]=s[i],也就是把“处理过的数据”后面再加一个,如果有就跳过,最后做完之后,再加个结尾符号即可。

代码如下(具体分析可参考http://stackoverflow.com/questions/2598129/function-to-remove-duplicate-characters-in-a-string):

void remove(char *str)
{
	if (str == NULL) return;
	int len = strlen(str);
	if (len < 2) return;
	int tail = 1;
	for (int i = 1; i < len; ++i) {
		int j;
		for (j = 0; j < tail; ++j) {
			if (str[i] == str[j]) break;
		}
		if (j == tail) {
			str[tail++] = str[i]; 
		}
  }
  str[tail] = 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值