data type range

数据类型一直都是麻烦事,看到剑指Offer上判溢出拿了范围更大的long long int来装可能溢出的int,于是总结各种数据类型的范围

int = long
unsigned int= unsigned long

这两中是最熟悉的,32bit 有符号位 -2^31~2^31-1 补码范围多一位,因为归到正数那边了,long 这个和他一样,不知道搞个这个出于什么目的。

long long 则是翻了一倍,64bit,unsigned long long 自然是 2^64-1 对应的数据范围,所以这个其实比较好理解,

double 则可以表示到10^308此方(1.79769e+308 ~ 2.22507e-308),long double则可以惊人的1.18973e+4932 ~ 3.3621e-4932

主要指导用long long 来处理范围更大的数据就可以了,2^31-1 好像是2147483647,大概12位,2^32-1是经典的4294967295,google直接计算很舒服,2^64-1是1.8446744e+19,20位,应该足够大了。

整数int,longlong
http://www.cnblogs.com/xiangshancuizhu/archive/2010/12/12/1903719.html
包含浮点数double long double等
http://blog.csdn.net/xuexiacm/article/details/8122267

Posted by richard爱闹 - 7月 14 2014
如需转载,请注明: 本文来自 Richard

StrToInt, not equal to atoi

这道题目当时写的leetcode那个其实还是不是非常好,因为只是和lib里atoi完全一致,但是他的很多需求很奇怪,我觉得还是要重新实现,
模仿July的需求来设计这个function,另外今天看到一个合法全数字的string到int的算法

int num=0;
while(*string!=\0')
{
    num=10*num+string-'0';
    string++;
}

当时还以为有问题,但是完全手动模拟发现完全正确,我一直都是按照weight来累加,先计算位数,然后weight逐个pow(10,weight)这样,居然看到这个很新鲜。
后来想想,这种迭代的严格来说都有个或简单或复杂的数学递推式,例如这里 an=a(n-1) 10+sn 其中下标是1-base, ai表示高位开始1到i位的十进制数,si表示从高位开始第i位数字,于是就
好理解了,1=0
10+1, 12=110+2,123=1210+3,于是可以这么迭代下去计算最后的值.而且我也感觉July给的答案也不是我那个代码的样子。。。

bool valid(char *str)
{
    int i=0;
    if((str[i]<='9' && str[i]>='0') || str[i] == '.'||str[i]=='+' || str[i]=='-')//first can be dot
        i++;
    else
        return false;
    int dotcount=0;
    while(i<strlen(str))
    {
        if((str[i]<='9' && str[i]>='0'))
            i++;
        else if (str[i]=='.')//dot can be any place
        {
            i++;
            dotcount++;
            if(dotcount>1)//only one dot
                return false;
        }
        else //invalid char
            return false;
    }
    return true;
}
bool invalid=false;//global value for invalid input parameter
int StrtoInt(char* str)
{
    int len;
    if(str==NULL) {cout<<"pointer NULL";invalid=true;return -1;}//-1 just can be any value, as a global value as flag
    if((len=strlen(str))==0) {cout<<"string NULL";invalid=true;return -1;}
    if(!valid(str)) {cout<<"not valid string";invalid=true;return -1;}
    int i=0;
    bool IsNegative=false;
    if(str[i]=='-')
    {
        IsNegative=true;
        i++;
    }
    else if(str[i]=='+')
    {
        i++;
    }
    else
        ;
    int num=0;
    bool overflow=false;
    while(i<len && str[i]!='.')
    {
        int originalnum=num;
        num=10*num+str[i]-'0';
        if(num>0 && originalnum <0 || num<0 && originalnum >0)
            overflow=true;
    }
    if(overflow==true)
    {
        cout<<"overflow";
        invalid=true;
        return -1;
    }
    if(i==len)
    {
        if(IsNegative==true)
            return -num;
        else
            return num;
    }
    else
    {
        i++;
        int weight=-1;
        while(i<len)
        {
            num+=pow(10,weight)*(str[i]-'0');//int not overflow, float can not overflow
            weight--;
        }
        if(IsNegative==true)
            return -num;
        else
            return num;
    }
}

代码写完了,
1)判断char* null, 空字符串(注意两者区别)
2)判断string has invalid char
3)符号处理(记得返回也要处理)
4)算值,整数部分新的迭代式,避免计算整数部分位数,小数部分用weight累加(记得判溢出,只需整数部分)
5)后处理negative 符号

不确定是否完全正确= = 由于LZ没有意识到返回Int竟然还算了小数部分,抱歉。。。。

最后发现书上答案是不需要单独去先遍历一遍去判断非法字符的,我感觉需求和书上还有有出入,例如只有 + - 或者这种非法都是返回0 而且不标记串非法。。。而且判溢出直接与最大数去比较,不是我这种
累加看是否正的变为负的。。。代码还是比那个麻烦。。

Posted by richard爱闹 - 7月 14 2014
如需转载,请注明: 本文来自 Richard

LCA of two nodes in tree

这道题目有几个版本,不同版本解法不一,还记得徐师兄好像当年QQ还是百度笔试有这道题目,不大确定,这也是剑指Offer最后一题 (LCA= lowest common ancestor)
Node FindLCA(Node root, Node p1, Node p2)

  1. 二叉有序树
    利用有序的性质,如果都在当前子树左边,往左边找,若都在右边,往右边找,若一左一右,返回,非常简明,一个while循环就出来了,
    因为每一步可以直接获得值,所以不需要递归 ,后面会遇到这种不能直接获得值得,可能就需要递归了

2.三叉链表
一般想到的都是有parent指针,这样会比较方便一点,分别从p1 p2到root,记录到两个另外的linklist,然后转化为
两个linklist第一个公共结点的位置,转化为编程之美的题目,各种方法都适用,例如先记录两个长度,然后指针对齐,在逐步后移。
从这里我联想到一个问题,因为二叉链表和单链表不一样,肯定要单独cppy到一个linklist里,但是不能只copy值。于是联想到linklist其实最本质的是结点的地址,例如编程之美那道,
是找到是否两个point值相同,而不是值,于是用存指针的数组是可以模拟两个链表相交的情况的,存值是不对的。当然解法里面用存address的linklist也是一个道理。

3.普通二叉树
1.递归算法:
感觉设计递归的时候,总是想到设计参数就比较麻烦,于是想到了一个方法,就是写成一个描述性的语句,里面包含的东西作为参数

找root 中p1 p2的LCA
if left tree 有p1 p2, right tree 无
找left tree中p1 p2的LCA
else if 左无,右有
找right tree中p1 p2的LCA
else 一有一无
return root

这样的话感觉结构很清晰,里面有两类描述语句,不知道是否可以统一成一个函数的功能。感觉好像不行,可能需要写一个判断二叉树是否有p1 p2这样一个函数。

  1. 非递归算法
    模仿三叉链表,既然没有parent,那就从root开始遍历找 到p1 p2的path,copy到linklist,然后从尾部开始找两个linklist的(FCN)first common node,但是看到的代码是从公共部分的一端开始,只要相同就覆盖,
    最后一次覆盖的也是前面开始的FCN

Posted by richard爱闹 - 7月 14 2014
如需转载,请注明: 本文来自 Richard

candy

需要将git的workspace移到hexo目录下才可以 hexo new ‘post’ 来生成新的.md文件。。。
leetcode一道candy题目,大意是每个小孩有打分,至少都有1个糖果,且比两个邻居(如果有的话)打分高的话要比邻居糖果多,求总的糖果至少多少?

我分析了之后,发现题目不明确,如果邻居相等的话,不知道多少,如果小于的话也没有说。这个先放下,一般是先分析general的情况。

一遍是不行的,因为可能后面降的时候,不知道降多少,可能不是decrease 1的降. 然后我在想,从前往后,再从后往前,其实有个解法是这样的,但我没有继续这么想。我想到的做法是,先把这些极小值点找出来,然后往上爬着增一定不会错,但是注意覆盖极大值的时候,可能被赋值两次,
于是要选择两者中较大的,打擂台完成。

先一遍遍历找极小值,然后后面遍历这个极小值index的数组,每个从两边(如果有的话)往上爬,直至极大值点。但是其实如果1 1 1 1 2 2 2 1 1 1 我就不清楚那些2应该给多少candy了,按道理的话他们都不满足比
两个邻居大,应该可以赋1的,但是我算出来是 2 1 2,结果还AC了,我感觉题目说不清楚。。。如果测试用例包含的情况足够的话。。。

最怕这种连题意都没完全理清楚,好像也没完全说清楚,但是又糊里糊涂的过了。。。

后来发现这位仁兄,非常简洁的两边扫描就完成了,往上增,右边也往上增,初始为1,比我的简洁多了。
http://zhaohongze.com/wordpress/2013/12/10/leetcode-candy/

int candy(vector<int>&ratings)
{
    int *candy=new int[ratings.size()]();//candy number of each child
    for(int i=0;i<ratings.size();i++)//initial 1, as some child that are not bigger than neighbors, but one bigger, one equal also one, not clear
        candy[i]=1;
    //memset(candy,1,sizeof(int)*ratings.size());//this can not memset, as memeset fill Bytes with 1, which make 0001000100010001(hex) like this, which is wrong, so memset can only zero(clear)
    //get min array
    vector<int> minvec;//min ratings array

    //int *minvec=new int[ratings.size()];

    int k;
    //create min index array
    for(int i=0;i<ratings.size();i++)
    {
        if(i-1>=0 && i+1 <= (ratings.size()-1) )
        {
            if(ratings.at(i-1) >= ratings.at(i) && ratings.at(i)<=ratings.at(i+1))//<= include equal or less than
            {
                //minvec[k]=i;
                candy[i]=1;
                //k++;
                minvec.push_back(i);
            }
        }
        else if( i-1 >= 0 && i+1 > (ratings.size()-1))
        {
            if(ratings.at(i-1) >= ratings.at(i))
            {
                candy[i]=1;
                minvec.push_back(i);
            }
        }
        else if( i-1 < 0 && i+1 <= (ratings.size()-1) )
        {
            if(ratings.at(i)<=ratings.at(i+1))
            {
                candy[i]=1;
                minvec.push_back(i);
            }
        }
    }

    //from min to two side increase
    for(int i=0;i<minvec.size();i++)
    {
        int j=minvec.at(i),k=j;
        while(j>=1 && ratings.at(j-1) > ratings.at(j))//equal would be as inital value, 1
        {
            if(candy[j-1] < candy[j]+1)//get max of two value
                candy[j-1]=candy[j]+1;
            j--;
        }

        j=k;
        while(j<=ratings.size()-2 && ratings.at(j) < ratings.at(j+1))
        {
            if(candy[j+1] < candy[j] +1)
                candy[j+1]=candy[j]+1;
            j++;
        }
    }

    int mincandy=0;
    for(int i=0;i<ratings.size();i++)
    {
        cout<<candy[i]<<" ";
        mincandy+=candy[i];
    }
    cout<<endl;
    //delete [] minvec;
    delete [] candy;
    return mincandy;
}

Posted by richard爱闹 - 7月 12 2014
如需转载,请注明: 本文来自 Richard

2 queue as 1 stack, 2 stack as 1 queue

另外这个hexo有个bug,经常会说landscape主题找不到,其实我都没有用这个主题,需要推倒hexo根目录上hexo clean一下 再hexo g, hexo d, 估计是tommy513写的有个bug,最后自己也没修复掉,
要是有人能找到问题原因还挺不错的~~~

2个栈边队列,设为A B

入队列: 入A

出队列: 如果|A|>0,pop A 到push B直到A只有一个元素,然后输出A达到先进先出,那么如果A空了,就直接pop B, 如果B也空了

    if A 不空: pop A 到push B直到A只有一个元素,然后popA中的这个元素
    else if B: 不空,popB
    else: 
        栈已空

感觉出入队列至少有一个O(n)的,不知道有没有O(1),都已经加了空间代价按道理有的。

2个队列变栈,设为A B
入栈:入A

出栈:(还没理清楚,感觉好像挺麻烦的,这个有通用的思路么)
由于队列倒来倒去顺序还是不变,所以比栈操作会更多一些,because pop and push stack can reverse the sequences.
所以队列是这样的,如果A不空,把A n-1个点逐个dequeue然后enqueue到B, 然后出第N个作为pop,如果A空,那么把B n-1 个点dequeue然后enqueue到A,然后第N个作为pop,一定是先看A,如果A空了再看B,因为入”栈”是从A入的

 if n=|A|>=1,dequeue A n-1 to B, dequeue A nth element 作为 "pop"
 else if |B|>=1 dequeue B n-1 to A, dequeue B nth element 作为 "pop"
 else 
    can not pop as stack empty

这种DS设计逻辑感觉没啥可以总结出的东西,没啥规律,有点靠灵光一现的感觉。。。感觉就是写几个case,然后归纳出一套处理的流程的规则之类的。。。。

现在想清楚了,总结一下,入的话都简单,选定一个例如A。出的时候根据DS 因地制宜,例如2 stack to be queue, 首先一开始如5个,然后”dequeue”, 将A n-1 pop push to B, 然后 pop A as “dequeue”, if “enqueue” 6, 6 should as the last,
so we can not first choose A for dequeue, instead choose B, if B empty, choose A. And must first if A, then else if B, can not effect the sequence to first if B, then else if A as data first into A then to B.so algorithm would be:

stack A B as queue

enqueue: push A
dequeue:
        if A not empty, pop A n-1 element to B, pop A nth element as "dequeue" // first would be all into A, as into "stack" or "queue", so element would first be A, then to B
        else if B not empty, pop B as "dequeue" //as when A element to B, its sequence reversed and fit for dequeue "first in first out", so directly pop B would be "dequeue"
        else
            "queue" empty, can not dequeue

queue A B as stack 

push: enqueue A
pop:  if n=|A|>=1,dequeue A n-1 to B, dequeue A nth element as "pop"// as first into A
      else if |B|>=1 dequeue B n-1 to A, dequeue B nth element as "pop"// queue is first in first out, and dequeue then enqueue would not effect its sequence
      else 
        can not pop as "stack" empty

Posted by richard爱闹 - 7月 12 2014
如需转载,请注明: 本文来自 Richard

isEndWith function error

博客和域名work不久,就出现了问题,说什么 TypeError, length of null啥的,一直以为是Markdown的语法不熟悉,但是一直调也弄不出,
后来决定定位js文件,在里面console.log(obj)把对应的schema.js文件里调用isEndWith的语句之前都print出来,发现一个url为null,而isEndWith是需要
取string的最后一个字符的,因此bug了,我不清楚url是由hexo.config.url赋值的,不清楚是啥含义,于是去twitter上问原作者台湾tommy351,他说是_config.yml里url的设定,
原来这里除了CNAME需要设置,还要设置这里的url项的,设置好之后,正常了~~~于是用了几套模板,diasy很好啊,就是代码太小了,改css太麻烦,于是暂时用phase模板,效果也挺赞的。

Posted by richard爱闹 - 7月 10 2014
如需转载,请注明: 本文来自 Richard

map for fast retreive and sort

之前写了几个map 算法,发现map比hash_map unordered_map都快,如果hash_map是因为正如群里所说的微软设计的一个比较挫的hash class,
那unordered_map慢就说不过去了吧,这可是STL,而且一开始以为unordered_set,这些都是C++ 11加进来的,但是set只能一个数据类型,我应用的时候
经常需要统计一个word的count就是一个pair了,所以还是unordered_map比较实用,用法和map一样,find和end()比,然后插入直接map[]=… 或者map.insert(make_pair(strng,int))这种的。
至于为啥慢我也不知道了。

另外还有unordered_multiset, unordered_multimap 是指key可以重复,对于multimap表示 , 对于multiset表示apple, apple 也即key可以重复的这种,一般很少用到

另外还有一个问题就是我需要对count进行排序咋办?

sort一般是对于里面容器是单个对象的,如果map不可以的,网上一个好的解决方案是赋给一个vector,里面是pair,然后根据pair的第二个成员 count来比较确定顺序,没有其他好的算法了,
unordered_map这种连key都是乱得,不然怎么交hash为杂凑:),map的key则是红黑树(有序二叉树),是有序的,但我们需要的是count排序。
http://stackoverflow.com/questions/1367429/sorting-a-stdmap-by-value-before-output-destroy

想一个简单的例子,百度很多日志,很多query,每个query是一个关键词string,外加其他属性例如IP, userid之类的,我们统计top10 query,那么就需要用这个了,查询高效,n次hash,O(n),
然后进行heapsort,O(n+10logn)=O(n),所以这里面先放到一个vector,然后根据value(count)进行建堆和调堆10次。这个算法在hash函数合理的情况下保证线性的时间复杂度,但是实际拿小数据测出来都
不如二叉树的查找效率#_#

这道题目和July著名博客的hash那篇的第一个例子很像,戳->http://blog.csdn.net/v_july_v/article/details/6256463

附上代码:

#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <map>
#include <hash_map>
#include <string>
#include <ctime>
#include <unordered_map>
#include <algorithm>
using namespace std;

void hashmap_wordcount()
{
    ifstream fin("E:\\2013-03-08-NTUInternship\\MetaSLForHuman\\Data\\WuMinCollectedFunctionalOrtholog\\HumanSL-YG-FunctionalSim.txt");
    if(fin==NULL) return ;
    string line,splitword;
    hash_map<string,int> wordcount; 
    while(getline(fin,line,'\n'))
    {
        istringstream istr(line);
        while(istr>>splitword)
        {
            //int splitnum=atoi(splitword.c_str());
            hash_map<string,int>::iterator it=wordcount.begin();
            if((it=wordcount.find(splitword))!=wordcount.end())
                //wordcount[splitword]++;
                it->second++;
            else
                //wordcount[splitword]=1; 
                wordcount.insert(make_pair<string,int>(splitword,1));
        }
    }
    /*
    for(hash_map<string,int>::iterator it=wordcount.begin();it!=wordcount.end();it++)
    {
        cout<<it->first<<" "<<it->second<<endl;
    }*/
}
void map_wordcount()
{
    ifstream fin("E:\\2013-03-08-NTUInternship\\MetaSLForHuman\\Data\\WuMinCollectedFunctionalOrtholog\\HumanSL-YG-FunctionalSim.txt");
    if(fin==NULL) return ;
    string line,splitword;
    map<string,int> wordcount; 
    while(getline(fin,line,'\n'))
    {
        istringstream istr(line);
        while(istr>>splitword)
        {
            //int splitnum=atoi(splitword.c_str());
            map<string,int>::iterator it=wordcount.begin();
            if((it=wordcount.find(splitword))!=wordcount.end())
                it->second++;
            else
                //wordcount[splitword]=1;
                wordcount.insert(make_pair<string,int>(splitword,1));
        }
    }/*
    for(map<string,int>::iterator it=wordcount.begin();it!=wordcount.end();it++)
    {
        cout<<it->first<<" "<<it->second<<endl;
    }*/
}
bool SortComp(const pair<string, int> p1, const pair<string, int>p2)
{
    return p1.second<p2.second;
}
void unordered_map_wordcount()
{
    unordered_map<string, int> wordcount;
    ifstream infile("E:\\2013-03-08-NTUInternship\\MetaSLForHuman\\Data\\WuMinCollectedFunctionalOrtholog\\HumanSL-YG-FunctionalSim.txt");
    string line; string splitword;
    while(getline(infile,line))
    {
        istringstream istr(line);
        while(istr>>splitword)//space or tab split default
        {
            if(wordcount.find(splitword)!=wordcount.end())//found
            {
                wordcount[splitword]++;
            }
            else
            {
                wordcount[splitword]=1;
            }
        }
    }
    vector<pair<string,int>> wordcountvec(wordcount.begin(),wordcount.end());

    sort(wordcountvec.begin(),wordcountvec.end(),SortComp);

    /*
    //find maxcount;
    unordered_map<string, int>::iterator it=wordcount.begin(),maxit;
    int maxcount=it->second;
    it++;
    while(it!=wordcount.end())
    {
        if(it->second>maxcount)
            maxit=it;
        //cout<<it->first<<" "<<it->second<<endl;
        it++;
    }
    */
}


int main()
{
    clock_t start,finish;
    start=clock();
    map_wordcount();
    finish=clock();
    cout<<(double)(finish-start)/CLOCKS_PER_SEC<<endl;
    start=clock();
    hashmap_wordcount();
    finish=clock();
    cout<<(double)(finish-start)/CLOCKS_PER_SEC<<endl;

    start=clock();
    unordered_map_wordcount();
    finish=clock();
    cout<<(double)(finish-start)/CLOCKS_PER_SEC<<endl;

    return 0;
}

Posted by richard爱闹 - 7月 10 2014
如需转载,请注明: 本文来自 Richard

buy a new domain temporarily not available for at most three days

再次感谢Zeppary大神,引导我买godaddy的域名,还有注册DNSPOD的DNS,大概一年70多人民币,.com域名要贵些,早知就买Info了

godaddy里面点了半天才到购买的页面,结果没提示设置nameserver,后来以为不能改白花了大洋,还好后面是可以改的,只是要等大概3天,DNS服务器
更新他的DNS到IP的list,其实这个流程是这样的,发送http请求, zhangruichang.com, 然后通过DNSPOD里面的record设置,跳转到zhangruichang.github.io,
然后映射到IP,便可以访问了。不确定是不是第二步才访问DNS server

http://zipperary.com/2013/05/27/domain-name-and-dns/

Posted by richard爱闹 - 7月 10 2014
如需转载,请注明: 本文来自 Richard

由字符串替换程设,发现string的find及replace使用陷阱

另外今天通过设置,可以避免每次update到github输入用户名密码的问题了,感谢Zippera大神: )
http://zipperary.com/2013/05/26/ssh-errors-with-github/

这是一道程设初级的题目,但是发现还是会遇到问题,字符串替换,我使用cpp string比较安全,find repalce函数

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iomanip>
#include <sstream>
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define read freopen("in.txt","r",stdin)  
#define write freopen("out.txt","w",stdout)
using namespace std;
int main()
{
    read;
    write;
    string str,oristr,newstr,sentence;
    vector<string> orivec;
    vector<string> newvec;
    while(getline(cin,str))
    {
        if(str.size()==0) break;//finish rule
        istringstream istr(str);
        getline(istr,oristr,'|');
        getline(istr,newstr,'|');
        orivec.push_back(oristr);
        newvec.push_back(newstr);
    }
    int startindex;
    while(getline(cin,sentence))
    {
        if(sentence.size()==0) continue;
        for(int i=0;i<orivec.size();i++)
        {

            while((startindex=sentence.find(orivec.at(i),0))!=-1)
            {
                sentence.replace(startindex,orivec.at(i).size(),newvec.at(i));
            }
        }
        break;
    }

    cout<<sentence<<endl;


    return 0;
}

问题1:find函数本来找不到是返回string::npos, 用这样一个静态变量表示找不到,类似于迭代器的end(),实际该位置是不存在合法字符的,但是VS确返回了-1,此时npos返回 2^32-1, 不知为何
经过July群里的大神解答,问题1解决,npos是 size_t 类型,32bit下是unsigned int, 是因为一个无符号数 32个1(无符号表示2^32-1) 赋给了一个有符号数(32个全1被认为是-1),所以 unsigned int 和 int比较的时候 都会转化为 int 然后其实 还是相等的,
或许npos是为了便于跨平台,因为到了64bit平台, 64全1,赋给符号整数也是作为补码,也是变为-1

问题2:replace函数一直担心如果替换后的字符串比源串长,如何不覆盖后面的字符,如果短,是否会自动拼接。回答,是的,会的,之前以为不会是因为用法不多,replace(start,length,string)中的length实际是原子串的长度,
而我以为是替换后的长度,怪不得用不对,以后可以避免了,还可以用迭代器替换index,尽管我不喜欢= = 另外发现cplusplus有个 cpp.sh 可以自动网页执行代码,威武啊!

Posted by richard爱闹 - 7月 10 2014
如需转载,请注明: 本文来自 Richard

left rotate string

我感觉这种不叫算法,叫一些小的tricks,就是换来换去,自己要理清楚,我想了一个基于交换的左旋算法,每次确定一个字符的最终位置,tmp记录下次
要确定位置的字符,i表示下一次要确定字符的当前的位置。

string LeftRotate(string str, int k)
{
    int i,n=str.size();
    if(k>=n || k<=0) return str;
    char tmp=str[k];
    int originalindex=k;
    i=k;
    for(int j=0;j<n;j++)
    {
        if(i>=k)
        {
            i=i-k;
        }
        else
        {
            i=n-k+i;
        }
        //originalindex=i;
        swap(tmp,str[i]);
        //tmp=str[i];
        //tmp2=tmp;
        //str[i]=tmp;
        //originalindex=i;
    }
    return str;
}

另外今天又遇到了可怕的cin问题,尽管官方都说了cin>>是臭名昭著的,但是我还是不痛不痒的用了几年,到时候每次整数和字符串混输入的时候都得小心,一个换行符都会被cin留在缓冲区里。。。

而且看到July大大总结的那么多算法好像都还没有我这个算法。

另外最简单的就是两部分分别逆置,然后总的逆置,来自编程珠玑,怎么感觉还想还有一个问题也是这样的,有点乱了。。。
对好像是 对每个单词逆置,然后整个字符串逆置,明白了,这个其实是用来解决 把word顺序逆置,但是word里字符的顺序不变,那么当分成两个部分的时候(字符串左旋问题),利用这个算法刚好可以完成这个目标,所以可以说字符串左旋
右旋可以说是这个算法的一个特殊情况,原始算法是泛化。。。不过都是线性算法。

问题过于经典,关于July大神著名博客此题的解法,戳 http://blog.csdn.net/v_july_v/article/details/6322882

Posted by richard爱闹 - 7月 10 2014
如需转载,请注明: 本文来自 Richard