31.第一个只出现一次的字符位置

第一个只出现一次的字符位置

题目描述

在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置。若为空串,返回-1。位置索引从0开始
虽说C++的string类用起来超爽,但是和平时的使用习惯不同,我更喜欢原滋原味的C风格字符。这道题我写了两个版本,一个是C++风格的string,另一个是C风格字符串。
注意, C风格字符串中判断是否到达字符串末尾的两种方法:
*p != '\0'
*p != 0
本质上是一回事。
string版:
#include "stdafx.h"
#include <string>
#include<iostream>
using namespace::std;
class Solution {
public:
	int FirstNotRepeatingChar(string str) {
		if (str.empty()) return -1;

		int arr[256] = { 0 };
		int length = str.length();
		for (int i = 0; i < length; i++){
			arr[(int)str[i]]++;
			std::cout << (int)str[i] << endl;
		}
		int retVal = 0;
		for (int i = 0; i < length; i++){
			if (arr[(int)str[i]] == 1)
				break;
			retVal++;
		}
		if (retVal == str.length()){
			retVal = -1;
		}
		return retVal;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	Solution s;
	string test = "asdfasdfe";
	int result = s.FirstNotRepeatingChar(test);
	return 0;
}

C风格字符串版:
#include "stdafx.h"
#include <string>
#include<iostream>
using namespace::std;
class Solution {
public:
	int FirstNotRepeatingChar(string str) {
		if (str.empty()) return -1;

		const char* p = str.data();
		int strLength = 0;
		int arr[256] = { 0 };
		while (*p != '\0'){
			arr[*p]++;
			p++;
			strLength++;
		}
		const char* p2 = str.c_str();
		int retVal = 0;
		while (*p2 != '\0'){
			if (arr[*p2] == 1)
				break;
			p2++; retVal++;
		}
		if (retVal == strLength){
			retVal = -1;
		}
		return retVal;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	Solution s;
	string test = "asdfasdfe";
	int result = s.FirstNotRepeatingChar(test);
	return 0;
}
说说这里面的坑:
string有两个函数可以转C风格字符串,一个是c_str(),另一个是data(),效果似乎相同,都会在字符串结尾补上'\0',关键是两个函数的返回值都是const char*指针
const char* p = str.data();
写成
char* p = str.data();
是通不过编译的。
第二次做:
第二次一来想到了map,遍历string时用map<char, int> 可以方便的记录字符char出现的次数,注意,map的底层数据结构是红黑树,按key值大小排序,map自动为我们排序,这反而打乱了字符在string出现的顺序,如果有字符a和字符b均在string出现一次,那么map的排序结果可能颠倒a、‘b顺序,从而导致我们不容易找出谁才是第一个出现一次的字符。
没办法,只好回到第一次做的老路子:
class Solution {
public:
	int FirstNotRepeatingChar(string str) {
    	if ( str.empty() == true ) return -1 ;
        
        int arr[256] = { 0 } ;
        
        for ( int i = 0; i < str.size(); ++ i ) {
            arr[ (int)str[i] ] ++ ;
        }
        
        int retVal = -1 ;
        for ( int i = 0; i < str.size(); ++ i ) {
            if ( arr[ (int)str[i] ] == 1 ) {
                retVal = i ;
                break ;
            }
        }
        return retVal ;
    }
};

第三次做:
class Solution {
public:
    int FirstNotRepeatingChar(string str) {
        if ( str.empty() ==true ) return -1 ;
        
        char c[256] = { 0 } ;
        
        for ( int i = 0; i < str.size(); ++ i ) {
            c[ (int)str[i] ] ++ ;
        }
        
        for ( int i = 0; i < str.size(); ++ i ) {
            if ( c[ (int)str[i] ] == 1 ) return i ;
        }
        
        return -1 ;
    }
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值