clang 简单的str_replace实现

本文探讨了三种不同的C语言中实现字符串替换功能的方法。通过分析str_replace、str_replace_2和str_replace_3函数,详细解释了每种方法的工作原理,并比较了它们的性能。这些函数可用于在字符串中查找特定子串并将其替换为另一子串。

自己写的一段:

//gool
char* str_replace(char* source, const  char* find, const char* replace){

	if (source == NULL || find == NULL || find == "")
		return strdup(source);
	
	int matchCount = 0;
	int nowIndex = 0;
	int findLength = strlen(find);
	int replaceLength = strlen(replace);
	int sourceLength = strlen(source);
	int resultLength = sourceLength;
	char* result;
	int i;
	for ( i = 0; i < sourceLength; i++)
	{
		if (nowIndex < findLength && source[i] == find[nowIndex]){
			nowIndex++;
			matchCount++;
		}
		else
		{
			if (matchCount == findLength)
			{
				source[i - 1] = '\0';
				nowIndex = 0;
				matchCount = 0;
				resultLength -= findLength - replaceLength;
			}
		}
	}

	nowIndex = 0;
	matchCount = 0;

	result = (char*)malloc(2 * (resultLength + 1));

	for ( i = 0; i < sourceLength; i++)
	{
		if (source[i] == '\0'){
			source[i] = find[0];
			while (matchCount < replaceLength)
			{
				*(result + nowIndex + matchCount) = replace[matchCount];
				matchCount++;
			}
			matchCount = 0;
			nowIndex += replaceLength;
			i += findLength -1;
		}
		else
		{
			*(result + nowIndex) = source[i];
			nowIndex++;
		}
	}
	*(result + nowIndex + 1) = '\0';
	return result;
}

  http://blog.youkuaiyun.com/glmmmm/article/details/9930969:

char *str_replace_2(const char *string, const char *substr, const char *replacement)
{
	char *tok = NULL;
	char *newstr = NULL;
	char *oldstr = NULL;

	/* if either substr or replacement is NULL, duplicate string a let caller handle it */
	if (substr == NULL || replacement == NULL)
		return strdup(string);

	newstr = strdup(string);
	while ((tok = strstr(newstr, substr)))
	{
		oldstr = newstr;
		newstr = (char*)malloc(strlen(oldstr) - strlen(substr) + strlen(replacement) + 1);
		/*failed to alloc mem, free old string and return NULL */
		if (newstr == NULL)
		{
			free(oldstr);
			return NULL;
		}
		memcpy(newstr, oldstr, tok - oldstr);
		memcpy(newstr + (tok - oldstr), replacement, strlen(replacement));
		memcpy(newstr + (tok - oldstr) + strlen(replacement), tok + strlen(substr), strlen(oldstr) - strlen(substr) - (tok - oldstr));
		memset(newstr + strlen(oldstr) - strlen(substr) + strlen(replacement), 0, 1);

		free(oldstr);
	}

	return newstr;
}

http://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in-c:

char *str_replace_3(char *orig, char *rep, char *with) {
	char *result; // the return string
	char *ins;    // the next insert point
	char *tmp;    // varies
	int len_rep;  // length of rep
	int len_with; // length of with
	int len_front; // distance between rep and end of last rep
	int count;    // number of replacements

	if (!orig)
		return NULL;
	if (!rep)
		rep = "";
	len_rep = strlen(rep);
	if (!with)
		with = "";
	len_with = strlen(with);

	ins = orig;
	for (count = 0; tmp = strstr(ins, rep); ++count) {
		ins = tmp + len_rep;
	}

	// first time through the loop, all the variable are set correctly
	// from here on,
	//    tmp points to the end of the result string
	//    ins points to the next occurrence of rep in orig
	//    orig points to the remainder of orig after "end of rep"
	tmp = result = (char*)malloc(strlen(orig) + (len_with - len_rep) * count + 1);

	if (!result)
		return NULL;

	while (count--) {
		ins = strstr(orig, rep);
		len_front = ins - orig;
		tmp = strncpy(tmp, orig, len_front) + len_front;
		tmp = strcpy(tmp, with) + len_with;
		orig += len_front + len_rep; // move to next "end of rep"
	}
	strcpy(tmp, orig);
	return result;
}

  

平均测速:1. 84 clock/100000,2. 195 clock/100000,3.89 clock/100000

转载于:https://www.cnblogs.com/Gool/p/3721322.html

def _write_back_in_block(self): """安全地一次性更新 C 文件中的数组和枚举定义""" if self.dry_run: self.logger.info("DRY-RUN: 跳过写入文件") return try: content = self.c_file_path.read_text(encoding='utf-8') start_idx = content.find(self.start_marker) end_idx = content.find(self.end_marker) + len(self.end_marker) if start_idx == -1 or end_idx == -1: raise ValueError("未找到 CHANNEL RANGES 标记块") header = content[:start_idx] footer = content[end_idx:] block = content[start_idx:end_idx] replacements = [] # (start, end, replacement) # === 工具函数:移除注释避免误匹配 === def remove_comments(text): text = re.sub(r'//.*$', '', text, flags=re.MULTILINE) text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL) return text clean_block = remove_comments(block) # === 1. 更新 channel_ranges_xxx[] 数组:只在末尾添加新项 === array_pattern = re.compile( r'(static\s+const\s+struct\s+clm_channel_range\s+(channel_ranges_[\w\d]+)\s*\[\s*\]\s*=\s*\{)([^}]*)};', re.DOTALL ) for match in array_pattern.finditer(clean_block): array_name = match.group(2) if array_name not in self.struct_entries: continue structs = self.struct_entries[array_name] body_content = match.group(3) # 不 strip(),保留原始空白 original_end = match.end() # 提取第一行缩进(用于新行) first_line = body_content.split('\n')[0] if body_content.strip() else "" indent_match = re.match(r'^(\s*)', first_line) indent = indent_match.group(1) if indent_match else " " # 解析已有 {low, high} 结构体 existing_items = [] item_pattern = r'\{\s*(\d+)\s*,\s*(\d+)\s*\}' for m in re.finditer(item_pattern, body_content): low, high = int(m.group(1)), int(m.group(2)) existing_items.append((low, high)) # 查找最后一个结构体结束位置(用于插入点) all_matches = list(re.finditer(item_pattern, body_content)) if all_matches: last_match = all_matches[-1] insert_pos_in_body = body_content.find('}', last_match.start()) + 1 else: insert_pos_in_body = len(body_content) # 找出第一个尚未插入的项 inserted_count = len(existing_items) if inserted_count >= len(structs): continue new_item = structs[inserted_count] low, high = new_item['low'], new_item['high'] # 检查是否已存在 if (low, high) in existing_items: continue # 构造新条目 formatted_item = f" {{ {low}, {high}}}" comma = ",\n" insertion = f"{indent}{formatted_item}{comma}" # 计算插入位置在整个 block 中的真实 offset body_start = match.start(3) insert_offset = body_start + insert_pos_in_body final_insert = block[:insert_offset] + insertion + block[insert_offset:] # 重建整个声明 new_decl = f"{match.group(1)}{final_insert[match.start(3):]}{indent}}};" replacements.append((match.start(), original_end, new_decl)) range_macro = f"RANGE_{array_name.upper().replace('CHANNEL_RANGES_', '').replace('_', '_')}_{low}_{high}" self.logger.info(f"扩展数组: {range_macro} → {{{low}, {high}}} (index={inserted_count})") # === 2. 更新 enum range_xxx:精确继承上一行宏名左对齐与 '=' 对齐 === enum_pattern = re.compile(r'(enum\s+range_[\w\d_]+\s*\{)([^}]*)\}\s*;', re.DOTALL) for match in enum_pattern.finditer(block): enum_name_match = re.search(r'range_([a-zA-Z0-9_]+)', match.group(0)) if not enum_name_match: continue inferred_array = f"channel_ranges_{enum_name_match.group(1)}" if inferred_array not in self.array_macros: continue macro_list = self.array_macros[inferred_array] enum_body = match.group(2) # 解析已有宏及其值 existing_macros = dict(re.findall(r'(RANGE_[\w\d_]+)\s*=\s*(\d+)', remove_comments(enum_body))) next_id = len(existing_macros) if next_id >= len(macro_list): continue new_macro = macro_list[next_id] # 获取非空行 lines = [line for line in enum_body.split('\n') if line.strip()] last_line = lines[-1] if lines else "" if not last_line.strip(): # fallback 缩进 line_indent = " " target_macro_start_col = 4 target_eq_col = 32 else: indent_match = re.match(r'^(\s*)', last_line) line_indent = indent_match.group(1) if indent_match else " " # 展开 tab(统一按 4 空格处理) expanded_last = last_line.expandtabs(4) # 👉 提取第一个 RANGE_xxx 宏名 first_macro_match = re.search(r'RANGE_[\w\d_]+', remove_comments(last_line)) if not first_macro_match: target_macro_start_col = len(line_indent) target_eq_col = 32 else: macro_text = first_macro_match.group(0) macro_start = first_macro_match.start() # 计算视觉起始列(基于展开后的字符串) raw_before = last_line[:macro_start] expanded_before = raw_before.expandtabs(4) target_macro_start_col = len(expanded_before) # 👉 找第一个 "=" 的视觉列 eq_match = re.search(r'=\s*\d+', last_line[macro_start:]) if eq_match: eq_abs_start = macro_start + eq_match.start() raw_eq_part = last_line[:eq_abs_start] expanded_eq_part = raw_eq_part.expandtabs(4) target_eq_col = len(expanded_eq_part) else: # fallback target_eq_col = target_macro_start_col + len(macro_text) + 8 # ✅ 现在我们知道: # - 宏名应该从第 target_macro_start_col 列开始(视觉) # - `=` 应该出现在 target_eq_col 列 # 计算当前宏名需要多少前置空格才能对齐 current_visual_len = len(new_macro.replace('\t', ' ')) padding_to_eq = max(1, target_eq_col - target_macro_start_col - current_visual_len) full_padding = ' ' * padding_to_eq formatted_new = f"{new_macro}{full_padding}= {next_id}" # 判断是否同行追加(最多 4 个) clean_last = remove_comments(last_line) visible_macros = len(re.findall(r'RANGE_[\w\d_]+', clean_last)) if visible_macros < 4 and last_line.strip(): # 同行追加:前面加两个空格分隔 separator = " " updated_content = last_line + separator + formatted_new + "," new_body = enum_body.rsplit(last_line, 1)[0] + updated_content else: # 换行:使用原始 indent 开头,然后补足到 target_macro_start_col raw_indent_len = len(line_indent.replace('\t', ' ')) leading_spaces_needed = max(0, target_macro_start_col - raw_indent_len) prefix_padding = ' ' * leading_spaces_needed new_line = f"{line_indent}{prefix_padding}{formatted_new}," trailing = enum_body.rstrip() maybe_comma = "," if not trailing.endswith(',') else "" new_body = f"{trailing}{maybe_comma}\n{new_line}" # 重建 enum new_enum = f"{match.group(1)}{new_body}\n}};" replacements.append((match.start(), match.end(), new_enum)) self.logger.info(f"扩展枚举: {new_macro} = {next_id}") # === 应用替换:倒序防止 offset 错乱 === replacements.sort(key=lambda x: x[0], reverse=True) result_block = block for start, end, r in replacements: result_block = result_block[:start] + r + result_block[end:] # 写回前备份 backup_path = self.c_file_path.with_suffix('.c.bak') copy2(self.c_file_path, backup_path) self.logger.info(f"已备份 → {backup_path}") # 写入新内容 self.c_file_path.write_text(header + result_block + footer, encoding='utf-8') self.logger.info(f"✅ 成功保存修改: {self.c_file_path}") except Exception as e: self.logger.error(f"写回文件失败: {e}", exc_info=True) raise def format_enum_item_aligned(reference_line: str, macro_name: str, value: int): """根据 reference_line 中最后一个宏的布局,返回对齐的新宏文本""" expanded_ref = reference_line.expandtabs(4) clean_ref = remove_comments(reference_line) matches = list(re.finditer(r'RANGE_[\w\d_]+\s*=\s*\d+', clean_ref)) if not matches: return f"{macro_name} = {value}" # fallback last_match = matches[-1] last_macro = last_match.group(0) start_in_ref = last_match.start() # 计算最后一个宏结束后的位置(含值) eq_match = re.search(r'=\s*\d+', last_macro) value_end_rel = eq_match.end() if eq_match else len(last_macro) value_abs_end = start_in_ref + value_end_rel # 获取其后的空白长度(决定间距) trailing = reference_line[value_abs_end:] spacing_match = re.match(r'\s*', trailing) inter_spacing = len(spacing_match.group(0)) # 计算新宏应从哪一列开始(视觉) prefix_until_value_end = reference_line[:value_abs_end] visual_end_pos = len(prefix_until_value_end.expandtabs(4)) + inter_spacing # 计算当前行已有内容的视觉长度(不含新增部分) base_part = reference_line[:value_abs_end + inter_spacing] base_visual_len = len(base_part.expandtabs(4)) # 新宏从 base_visual_len 开始 macro_visual_len = len(macro_name.replace('\t', ' ')) padding_len = max(1, visual_end_pos - base_visual_len - macro_visual_len) padding = ' ' * padding_len return f"{macro_name}{padding}= {value}" 在此基础上修改
10-17
基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值