字符串

字符串

1、整数转换为字符串

1.1 iota

char* _itoa(int value, char* string, int radix)
{
 char tmp[33];
 char* tp = tmp;
 int i;
 unsigned v;
 int sign;
 char* sp;
 if (radix > 36 || radix <= 1)
 {
  __set_errno(EDOM);
  return 0;
 }
 sign = (radix == 10 && value < 0);
 if (sign)
  v = -value;
 else
  v = (unsigned)value;
 while (v || tp == tmp)
 {
  i = v % radix;
  v = v / radix;
  if (i < 10)
   *tp++ = i+''0'';
  else
   *tp++ = i + ''a'' - 10;
 }
 if (string == 0)
  string = (char*)malloc((tp-tmp)+sign+1);
 sp = string;
 if (sign)
  *sp++ = ''-'';
 while (tp > tmp)
  *sp++ = *--tp;
 *sp = 0;
 return string;
}


 2.字符串转换为整型

2.1 atoi(只支持十进制)

/***
*atox.c - atoi and atol conversion
*
* Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* Converts a character string into an int or long.
*
*******************************************************************************/

#include <cruntime.h>
#include <stdlib.h>
#include <ctype.h>

/***
*long atol(char *nptr) - Convert string to long
*
*Purpose:
* Converts ASCII string pointed to by nptr to binary.
* Overflow is not detected.
*
*Entry:
* nptr = ptr to string to convert
*
*Exit:
* return long int value of the string
*
*Exceptions:
* None - overflow is not detected.
*
*******************************************************************************/

long __cdecl atol(
const char *nptr
)
{
int c; /* current char */
long total; /* current total */
int sign; /* if ''-'', then negative, otherwise positive */

/* skip whitespace */
while ( isspace((int)(unsigned char)*nptr) )
++nptr;

c = (int)(unsigned char)*nptr++;
sign = c; /* save sign indication */
if (c == ''-'' || c == ''+'')
c = (int)(unsigned char)*nptr++; /* skip sign */

total = 0;

while (isdigit(c)) {
total = 10 * total + (c - ''0''); /* accumulate digit */
c = (int)(unsigned char)*nptr++; /* get next char */
}

if (sign == ''-'')
return -total;
else
return total; /* return result, negated if necessary */
}


/***
*int atoi(char *nptr) - Convert string to long
*
*Purpose:
* Converts ASCII string pointed to by nptr to binary.
* Overflow is not detected. Because of this, we can just use
* atol().
*
*Entry:
* nptr = ptr to string to convert
*
*Exit:
* return int value of the string
*
*Exceptions:
* None - overflow is not detected.
*
*******************************************************************************/

int __cdecl atoi(
const char *nptr
)
{
return (int)atol(nptr);
}

#ifndef _NO_INT64

__int64 __cdecl _atoi64(
const char *nptr
)
{
int c; /* current char */
__int64 total; /* current total */
int sign; /* if ''-'', then negative, otherwise positive */

/* skip whitespace */
while ( isspace((int)(unsigned char)*nptr) )
++nptr;

c = (int)(unsigned char)*nptr++;
sign = c; /* save sign indication */
if (c == ''-'' || c == ''+'')
c = (int)(unsigned char)*nptr++; /* skip sign */

total = 0;

while (isdigit(c)) {
total = 10 * total + (c - ''0''); /* accumulate digit */
c = (int)(unsigned char)*nptr++; /* get next char */
}

if (sign == ''-'')
return -total;
else
return total; /* return result, negated if necessary */
}

#endif /* _NO_INT64 */


#include <msvcrt/errno.h>
#include <msvcrt/stdlib.h>
#include <msvcrt/internal/file.h>
char* _itoa(int value, char* string, int radix)
{
char tmp[33];
char* tp = tmp;
int i;
unsigned v;
int sign;
char* sp;

if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}

sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+''0'';
else
*tp++ = i + ''a'' - 10;
}

if (string == 0)
string = (char*)malloc((tp-tmp)+sign+1);
sp = string;

if (sign)
*sp++ = ''-'';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}

 

2.2 strtol(支持任意进制)

long int strtol(const char *nptr,char **endptr,int base);
这个函数会将参数nptr字符串根据参数base来转换成长整型数。
参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换。
一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('\0')结束转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符 指针由endptr返回;若参数endptr为NULL,则会不返回非法字符串。
/**-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. [rescinded 22 July 1999]
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**

@deftypefn Supplemental {long int} strtol (const char *@var{string}, char **@var{endptr}, int @var{base})
@deftypefnx Supplemental {unsigned long int} strtoul (const char *@var{string}, char **@var{endptr}, int @var{base})

The @code{strtol} function converts the string in @var{string} to a
long integer value according to the given @var{base}, which must be
between 2 and 36 inclusive, or be the special value 0.  If @var{base}
is 0, @code{strtol} will look for the prefixes @code{0} and @code{0x}
to indicate bases 8 and 16, respectively, else default to base 10.
When the base is 16 (either explicitly or implicitly), a prefix of
@code{0x} is allowed.  The handling of @var{endptr} is as that of
@code{strtod} above.  The @code{strtoul} function is the same, except
that the converted value is unsigned.

@end deftypefn

*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <errno.h>
#ifdef NEED_DECLARATION_ERRNO
extern int errno;
#endif
#include "safe-ctype.h"

/** FIXME: It'd be nice to configure around these, but the include files are too
   painful.  These macros should at least be more portable than hardwired hex
   constants. */

#ifndef ULONG_MAX
#define	ULONG_MAX	((unsigned long)(~0L))		/** 0xFFFFFFFF */
#endif

#ifndef LONG_MAX
#define	LONG_MAX	((long)(ULONG_MAX >> 1))	/** 0x7FFFFFFF */
#endif

#ifndef LONG_MIN
#define	LONG_MIN	((long)(~LONG_MAX))		/** 0x80000000 */
#endif

/**
 * Convert a string to a long integer.
 *
 * Ignores `locale' stuff.  Assumes that the upper and lower case
 * alphabets and digits are each contiguous.
 */
long
strtol(const char *nptr, char **endptr, register int base)
{
	register const char *s = nptr;
	register unsigned long acc;
	register int c;
	register unsigned long cutoff;
	register int neg = 0, any, cutlim;

	/**
	 * Skip white space and pick up leading +/- sign if any.
	 * If base is 0, allow 0x for hex and 0 for octal, else
	 * assume decimal; if base is already 16, allow 0x.
	 */
	do {
		c = *s++;
	} while (ISSPACE(c));
	if (c == '-') {
		neg = 1;
		c = *s++;
	} else if (c == '+')
		c = *s++;
	if ((base == 0 || base == 16) &&
	    c == '0' && (*s == 'x' || *s == 'X')) {
		c = s[1];
		s += 2;
		base = 16;
	}
	if (base == 0)
		base = c == '0' ? 8 : 10;

	/**
	 * Compute the cutoff value between legal numbers and illegal
	 * numbers.  That is the largest legal value, divided by the
	 * base.  An input number that is greater than this value, if
	 * followed by a legal input character, is too big.  One that
	 * is equal to this value may be valid or not; the limit
	 * between valid and invalid numbers is then based on the last
	 * digit.  For instance, if the range for longs is
	 * [-2147483648..2147483647] and the input base is 10,
	 * cutoff will be set to 214748364 and cutlim to either
	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
	 * the number is too big, and we will return a range error.
	 *
	 * Set any if any `digits' consumed; make it negative to indicate
	 * overflow.
	 */
	cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
	cutlim = cutoff % (unsigned long)base;
	cutoff /= (unsigned long)base;
	for (acc = 0, any = 0;; c = *s++) {
		if (ISDIGIT(c))
			c -= '0';
		else if (ISALPHA(c))
			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
		else
			break;
		if (c >= base)
			break;
		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
			any = -1;
		else {
			any = 1;
			acc *= base;
			acc += c;
		}
	}
	if (any < 0) {
		acc = neg ? LONG_MIN : LONG_MAX;
		errno = ERANGE;
	} else if (neg)
		acc = -acc;
	if (endptr != 0)
		*endptr = (char *) (any ? s - 1 : nptr);
	return (acc);
}

3.大数加法

#include<stdio.h>
#include<string.h>
#define Max 101
void print(char sum[]);
void bigNumAdd(char a[],char b[],char sum[]);
int main()
{
	char a[Max];
	char b[Max];
	char sum[Max];
	gets(a);
	gets(b);
	bigNumAdd(a,b,sum);
	print(sum);
	return 0;
}
 
void bigNumAdd(char a[],char b[],char sum[])
{
	int i=0;
	int c=0;//表示进位
          //初始化,对以后位运算有很大帮助!
	char m[Max]={0};
	char n[Max]={0};
	memset(sum,0,Max*sizeof(char)); //这里不能写成memset(sum,0,sizeof(sum));原因见注意事项1
	//字符串反转且字符串变数字
	int lenA=strlen(a);
	int lenB=strlen(b);
	for (i=0;i<lenA;i++)
	{
		m[i]=a[lenA-i-1]-'0';
	}
	for (i=0;i<lenB;i++)
	{
		n[i]=b[lenB-i-1]-'0';
	}
	//位运算
	for (i=0;i<lenA||i<lenB;i++)
	{
		sum[i]=(m[i]+n[i]+c)%10+'0';//得到末位
		c=(m[i]+n[i]+c)/10;//得到进位
	}
}
 
void print(char sum[])
{
	int i=0;
	int j=0;
	int len = strlen(sum);
	for (i=len-1;sum[i]==0;i--); //找到第一个不为零的位置,方便输出
	for (j=i;j>=0;j--)
	{
		printf("%c",sum[j]);
	}
}

 

4.大数乘法

# include<stdio.h>
# include<string.h>
# include<malloc.h>

void multiply(char* a,char* b,char* c)
{
    int i,j,ca,cb,* s;
    ca=strlen(a);
    cb=strlen(b);
    s=(int*)malloc(sizeof(int)*(ca+cb));
    for (i=0;i<ca+cb;i++)
    	s[i]=0;
    for (i=0;i<ca;i++)
    	for (j=0;j<cb;j++)
    		s[i+j+1]+=(a[i]-'0')*(b[j]-'0');
    for (i=ca+cb-1;i>=0;i--)
    	if (s[i]>=10)
    	{
    	    s[i-1]+=s[i]/10;
    	    s[i]%=10;
        }
    i=0;
    while (s[i]==0)
    	i++;
   	for (j=0;i<ca+cb;i++,j++)
   		c[j]=s[i]+'0';
    c[j]='\0';
    free(s);
}

5.字符串拷贝

5.1 strcpy

char* strcpy(char* dst,const char* src)
{
     char* ptr=dst;
     while(*ptr++=*src++)
     ;
     return dst;
}


 6.字符串查找

6.1 strstr

char* strstr(char* buf,char* sub)
{
      char* ptr;
      char* subptr;
      
        
      while(*buf)
     {
           ptr =buf;
           subptr = sub;
           do{
              if(!*subPtr)
                  return buf;
          }while(*subptr++==*ptr++);
          buf+=1;
     }
     return 0;
}


 7.字符串循环移位

编写一个函数,作用是将一个char组成的字符串循环右移n个,比如原来是"abcdefghi",如果n为2的话,则移位后应该是"hiabcdefg"。

void LoopMove(char* ptr,int steps)
{
     int len = strlen(ptr);
     char* tmp = (char*)malloc(len+1);
     
     memset(tmp,0,sizeof(len+1);

     steps = steps%len;
     if(steps)
    {
         strcpy(tmp,ptr+len-steps);
         *(ptr+len-steps)='\0';
         strcpy(tmp+steps,ptr);
    }
    strcpy(ptr,tmp);
    return;
}

8.求字符串的最长重复子串

 

9.字符串过滤

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉。

比如字符串“abacacde”过滤结果为“abcde”。

要求实现函数:void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr);

void stringFilter(const char *pInputStr, long lInputLen, char *pOutputStr)
{
     assert(pInputStr != NULL);
     int i = 0;

     if (pInputStr == NULL || lInputLen <= 1)
     {
           return;
     }
     const char *p = pInputStr;
     while(*p != '\0')
     {
           if (g_flag[(*p - 'a')])
               p++;
           else{
              pOutputStr[i++] = *p;
              g_flag[*p - 'a'] = 1;
              p++;
           }
           pOutputStr[i] = '\0';
     }

}

 

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。

压缩规则:

1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。

2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。

要求实现函数:

void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);


10.字符串的格式化

10.1 大小写字母

给一个字符串,有大小写字母,要求写一个函数把小写字母放在前面,大写字母放在后面,尽量使用最小的空间、时间复杂度。

void move_char(char* a)
{
    char* i = a;
    char* j = a+strlen(a)-1;
    while(i < j)
    {
        while(*i && (*i>='a' && *i<='z'))
            ++i;
        if((*i) == '\0') break;
        while(*j>='A' && *j<='Z')
            --j;
        if(i < j)
        {
            char c = *i;
            *i = *j;
            *j = c;
        }
        ++i; --j;
    }
}


 

10.2 *移位

编写字符串处理函数,将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。如原始串为:ab**cd**e*12,处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)

int partitionStar(char a[],int len)
{
    int count = 0;
    int i = len-1;
    int j = len-1; //j指向第一个'*'
    while(i >= 0)
    {
        if (a[i] !=  '*')
        {
            swap(a[i--], a[j--]);
        }
        else
        {
            i--; count++;
        }
    }
    return count;
}


 

10.3

删除字符串中的数字并压缩字符串。如字符串"abc123de4fg56"处理后变为"abcdefg"。注意空间和效率。

char* delete_digits(char* str)
{
    char* i = str; // i for cursor, j for the first digit char;
    char* j = str;
    while(*i != '\0')
    {
        if (*i<'0' || *i>'9')
        {
            *j++ = *i++;
        }
        else
        {
            ++i;
        }
    }
    *j ='\0';
    return str;
}


10.4

删除特定字符:写一个高效的函数,删除字符串里给定的字符

void Remove_chars(char str[], char remove[])
{
    int remove_arr[256];
    for(int i=0; i<256; ++i)
        remove_arr[i] = 0;
    for(int i=0; remove[i]; ++i)
        remove_arr[remove[i]] = 1;
    int i = 0;
    for(int j=0; str[j]; ++j)
    {
        if(!remove_arr[str[j]])
            str[i++] = str[j];
    }
    str[i]='\0';
}


11 回文字符串

 

递归的结束需要简单情景

1. 字符串长度可能会奇数或偶数:

  • 如果字符串长度是奇数,字符串会剩下最中间那位字符,但其不影响回文。当检查到长度为1的时候即代表此字符串是回文
  • 如果字符串长度是偶数,当两端的字符串两两比较检查后不会剩下字符。即检查到长度为0的时候即代表此字符串是回文

2. 如果检查到两端两个字符不相同。则说明此字符串不是回文,直接返回0,不需要继续检查

 

#include <iostream>
using namespace std;
int fun(int low, int high, char *str, int length)
{
	if (length == 0 || length == 1)
		return    1;
	if (str[low] != str[high])
		return    0;
	return fun(low+1, high-1, str, length-2);
}
int main()
{
	char    str[]="aaabdaaa";
	int     length = strlen(str);
	//返回1代表是, 0代表不是
	cout << fun(0, length-1, str, length) << endl;
	return    0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值