string中的find函数和string::npos的使用

转载至http://www.cnblogs.com/web100/archive/2012/12/02/cpp-string-find-npos.html
查找字符串a是否包含子串b,
不是用strA.find(strB) > 0而是strA.find(strB) != string:npos
string::size_type pos = strA.find(strB);
if(pos != string::npos){}
-------------------------------------------
int idx = str.find("abc");
if (idx == string::npos)
...
上述代码中,idx的类型被定义为int,这是错误的,即使定义为 unsigned int 也是错的,它必须定义为 string::size_type。
npos 是这样定义的:
static const size_type npos = -1;

因为 string::size_type (由字符串配置器 allocator 定义) 描述的是 size,故需为无符号整数型别。因为缺省配置器以型别 size_t 作为 size_type,于是 -1 被转换为无符号整数型别,npos 也就成了该型别的最大无符号值。不过实际数值还是取决于型别 size_type 的实际定义。不幸的是这些最大值都不相同。事实上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是两者型别大小不同)。因此,比较式 idx == string::npos 中,如果 idx 的值为-1,由于 idx 和字符串string::npos 型别不同,比较结果可能得到 false。
要想判断 find() 的结果是否为npos,最好的办法是直接比较:

if (str.find("abc") == string::npos) { ... }

错误:if(str.find("abc") ) 
注:找不到abc会返回-1,不为0为True。0为False 
------------------------------------------------
复制代码
  /// /find函数返回类型 size_type
string s( " 1a2b3c4d5e6f7g8h9i1a2b3c4d5e6f7g8ha9i ");
string flag;
string::size_type position;

// find 函数 返回jk 在s 中的下标位置 
position = s.find( " jk ");
  if (position != s.npos)   // 如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,
 {
  cout <<  " position is :  " << position << endl;
 }
  else
 {
  cout <<  " Not found the flag " + flag;
 } 


// find 函数 返回flag 中任意字符 在s 中第一次出现的下标位置
 flag =  " c ";
 position = s.find_first_of(flag);
 cout <<  " s.find_first_of(flag) is :  " << position << endl;

  // 从字符串s 下标5开始,查找字符串b ,返回b 在s 中的下标
 position=s.find( " b ", 5);
 cout<< " s.find(b,5) is :  "<<position<<endl;

// 查找s 中flag 出现的所有位置。
 flag= " a ";
 position= 0;
  int i= 1;
  while((position=s.find_first_of(flag,position))!= string::npos)
 {
   // position=s.find_first_of(flag,position);
  cout<< " position   "<<i<< "  :  "<<position<<endl;
  position++;
  i++;
 }

  // 查找flag 中与s 第一个不匹配的位置
 flag= " acb12389efgxyz789 ";
 position=flag.find_first_not_of (s);
 cout<< " flag.find_first_not_of (s) : "<<position<<endl;


  // 反向查找,flag 在s 中最后出现的位置
 flag= " 3 ";
 position=s.rfind (flag);
 cout<< " s.rfind (flag) : "<<position<<endl;
}
复制代码
说明:

1.  如果string sub = ”abc“;

              string s = ”cdeabcigld“;

     s.find(sub) , s.rfind(sub) 这两个函数,如果完全匹配,才返回匹配的索引,即:当s中含有abc三个连续的字母时,才返回当前索引。

     s.find_first_of(sub),   s.find_first_not_of(sub),   s.find_last_of(sub),  s.find_last_not_of(sub)  这四个函数,查找s中含有sub中任意字母的索引。

2.  如果没有查询到,则返回string::npos,这是一个很大的数,其值不需要知道。

------------------

------------------

B. Mike and strings
time limit per test
 2 seconds
memory limit per test
 256 megabytes
input
 standard input
output
 standard output

Mike has n strings s1, s2, ..., sn each consisting of lowercase English letters. In one move he can choose a string si, erase the first character and append it to the end of the string. For example, if he has the string "coolmike", in one move he can transform it into the string "oolmikec".

Now Mike asks himself: what is minimal number of moves that he needs to do in order to make all the strings equal?

Input

The first line contains integer n (1 ≤ n ≤ 50) — the number of strings.

This is followed by n lines which contain a string each. The i-th line corresponding to string si. Lengths of strings are equal. Lengths of each string is positive and don't exceed 50.

Output

Print the minimal number of moves Mike needs in order to make all the strings equal or print  - 1 if there is no solution.

Examples
input
4
xzzwo
zwoxz
zzwox
xzzwo
output
5
input
2
molzv
lzvmo
output
2
input
3
kc
kc
kc
output
0
input
3
aa
aa
ab
output
-1
Note

In the first sample testcase the optimal scenario is to perform operations in such a way as to transform all strings into "zwoxz".


题解:重点在于怎么在某个目标字符串中找到匹配串,因为有可更换的操作,需要统计操作步数最小数。

有两种方法,

第一种,写一个change函数,每次将首字母放到字符串末尾,统计多少次change操作之后可以和目标字符串匹配成功。

第二种,新开一个中间字符串量,设定为目标字符串+目标字符串,从而可以之间在中间量中之间使用string类内置的find函数/

此处采取第二种方法,代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define INF 0x3f3f3f3f
int main(){
    string s[100];
    int n;
    int i,j;
    scanf("%d",&n);
    for(i = 0; i < n; i++)
        cin >> s[i];
    int step,minstep = INF;
    for(i = 0; i < n; i++){
        step = 0;
        string temp;
        for(j = 0; j < n; j++){
            if(i != j){
                temp = s[j]+s[j];
                if(temp.find(s[i])==string::npos){//说明没有找到,若找到返回位置
                    return cout << -1,0;//cout不是函数所以输出后要最后返回0,所以用逗号隔开
                }
                step += temp.find(s[i]);
            }
        }
        minstep = min(step,minstep);
    }
    cout << minstep << endl;
    return 0;
}
载至http://blog.csdn.net/nice_punch/article/details/70466681

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值