D语言字符串转C语言char*类型高效方法:性能比较与优化
D语言字符串转C语言char*类型高效方法:性能比较与优化
本文将探讨在D语言中将字符串转换为C语言char*类型的高效方法,并对不同方法的性能进行比较。同时,我们将介绍使用D语言内置的std.algorithm.replace函数优化字符串替换操作的示例代码,提升程序效率。
1. 核心代码实现与分析
import std.stdio;
import core.stdc.stdio:printf;
import core.stdc.string;
import core.stdc.stdlib : malloc, free;
import core.stdc.ctype:tolower;
import std:toUTFz;
import std.string:fromStringz,toStringz;
import std.datetime;
import std.conv:to;
/** 判断字符串是否以\0结束 **/
bool isStringEndsWithEmptyChar(string allStr)
{
if(allStr[$-1] == '\0')
{
return true;
}
auto thePtr = allStr.ptr;
if(thePtr[allStr.length]=='\0')
{
return true;
}
return false;
}
/**
转为c语言char*类型
1,最后一个字符是否为\0空字符,如果是则直接转为c语言的char*
2,不是根据情况是否产生新的,比如判断是否是常量区域字符串
**/
char* toCharPtrByUtf(string allStr,bool isCanWrite=false)
{
auto thePtr = allStr.ptr;
bool isHasEmpty = isStringEndsWithEmptyChar(allStr);
if(!isCanWrite)
{
if(isHasEmpty)
{
return cast(char*)thePtr;
}
else
{
return toUTFz!(char*)(allStr);
}
}
//不是指向常量数据区域的指针
if (cast(ulong) thePtr >= 0x400000 && cast(ulong) thePtr <= 0x600000)
{
return toUTFz!(char*)(allStr);
}
if(isHasEmpty)
{
return cast(char*)thePtr;
}
else
{
return toUTFz!(char*)(allStr);
}
}
/**
转为c语言char*类型
1,最后一个字符是否为\0空字符,如果是则直接转为c语言的char*
2,总会复制一个信的字符串,利用toStringz
**/
char* toCharPtr(string allStr,bool isCanWrite=false)
{
auto thePtr = allStr.ptr;
bool isHasEmpty = isStringEndsWithEmptyChar(allStr);
if(!isCanWrite)
{
if(isHasEmpty)
{
return cast(char*)thePtr;
}
else
{
return cast(char*)(toStringz(allStr));
}
}
//不是指向常量数据区域的指针
if (cast(ulong) thePtr >= 0x400000 && cast(ulong) thePtr <= 0x600000)
{
return cast(char*)(toStringz(allStr));
}
if(isHasEmpty)
{
return cast(char*)thePtr;
}
else
{
return cast(char*)(toStringz(allStr));
}
}
/**
转为c语言const char*类型
**/
const(char) * toConstCharPtrByUtf(string allStr)
{
auto thePtr = allStr.ptr;
bool isHasEmpty = isStringEndsWithEmptyChar(allStr);
if(isHasEmpty)
{
return thePtr;
}
else
{
return toUTFz!(const(char) *)(allStr);
}
}
/**
转为c语言const char*类型
**/
const(char) * toConstCharPtr(string allStr)
{
auto thePtr = allStr.ptr;
bool isHasEmpty = isStringEndsWithEmptyChar(allStr);
if(isHasEmpty)
{
return thePtr;
}
else
{
return cast(const(char) *)(toStringz(allStr));
}
}
// 判断两个字符是否相等,根据 isCaseSensitive 参数决定是否区分大小写
private bool charEqual(char a, char b, bool isCaseSensitive) @nogc nothrow
{
if (isCaseSensitive)
{
return a == b;
}
else
{
return tolower(a) == tolower(b);
}
}
// 在字符串 haystack 中查找第一次出现 needle 的位置,返回指向该位置的指针,如果找不到则返回 null
private char* strstrCase(char* haystack, const char* needle, bool isCaseSensitive) @nogc nothrow
{
if (!haystack || !needle || !*needle)
{
return haystack;
}
size_t haystackLen = strlen(haystack);
size_t needleLen = strlen(needle);
if (needleLen > haystackLen)
{
return null;
}
if (isCaseSensitive)
{
return strstr(haystack, needle);
}
for (size_t i = 0; i <= haystackLen - needleLen; i++)
{
bool found = true;
for (size_t j = 0; j < needleLen; j++)
{
if (!charEqual(haystack[i + j], needle[j], isCaseSensitive))
{
found = false;
break;
}
}
if (found)
{
return haystack + i;
}
}
return null;
}
char* replaceCstr(const char* allStr, const char* searchStr, const char* replaceStr, bool isCaseSensitive=true) @nogc nothrow
{
if (!allStr || !searchStr || !replaceStr || !*searchStr)
{
return cast(char*)allStr;
}
char* result = null;
ulong searchStrLength = strlen(searchStr);
ulong replaceStrLength = strlen(replaceStr);
ulong count = 0;
char* p = cast(char*)allStr;
while ((p = strstrCase(p, searchStr, isCaseSensitive)) != null)
{
count++;
p += searchStrLength;
}
if (count == 0)
{
return cast(char*)allStr;
}
ulong newStrLength = strlen(allStr) + count * (replaceStrLength - searchStrLength);
result = cast(char*) malloc(newStrLength + 1);
char* q = result;
p = cast(char*)allStr;
while (count-- > 0)
{
char* r = strstrCase(p, searchStr, isCaseSensitive);
long length = r - p;
memmove(q, p, length);
q += length;
memcpy(q, replaceStr, replaceStrLength);
q += replaceStrLength;
p = r + searchStrLength;
}
strcpy(q, p);
return result;
}
void main()
{
auto start = Clock.currTime();
string str = 'hello, world!';
const(char*) oldptr = toConstCharPtr(str);
char* now = null;
for (int ii = 0; ii < 10000000; ii++)
{
now = replaceCstr(oldptr,"o".ptr,"O".ptr);
now = replaceCstr(oldptr,"l".ptr,"1".ptr);
now = replaceCstr(oldptr,",".ptr,"".ptr);
now = replaceCstr(oldptr,"!".ptr,"".ptr);
//str = str.replaceString("o", "0").replaceString("l", "1").replaceString(",", "").replaceString("!", "");
}
if(oldptr!=now)
{
free(now);
}
auto end = Clock.currTime();
writeln("D语言程序运行时间 :", end-start);
}
replaceCstr函数实现效率比较低,请给出你能实现相同功能的最高效算法内容:可以考虑使用D语言内置的std.algorithm.replace函数,它可以在字符串中替换指定的子字符串。这个函数的实现效率比手写的replaceCstr函数要高很多。
下面是使用std.algorithm.replace实现的代码:
```d
import std.stdio;
import std.algorithm;
import std.datetime;
void main()
{
auto start = Clock.currTime();
string str = 'hello, world!';
for (int ii = 0; ii < 10000000; ii++)
{
str = str.replace("o", "O").replace("l", "1").replace(",", "").replace("!", "");
}
auto end = Clock.currTime();
writeln("D语言程序运行时间 :", end-start);
}
原文地址: https://www.cveoy.top/t/topic/jomG 著作权归作者所有。请勿转载和采集!