【C-算法题】The Old Key古老的密码之解

本文介绍了一个字符串匹配算法的具体实现,通过C语言代码展示了如何比较两个字符串的字符频率分布,并判断它们是否相同。该算法首先统计每个字符串中各字符出现的次数,然后对计数结果进行排序并比较,以此来确定两个字符串是否包含相同的字符频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100+10
int comp(const void *a,const void *b)
{
 return *(int *)a-*(int *)b;
}
int main()
{
 char s1[MAX],s2[MAX];
 int cnt1[26],cnt2[26];
 while(scanf("%s%s",s1,s2)!=EOF)
 {
    
  int l=strlen(s1);
  memset(cnt1,0,sizeof(cnt1));
  memset(cnt2,0,sizeof(cnt2));
  
  for(int i=0;i<l;i++)
  {
   cnt1[s1[i]-'A']++;
   cnt2[s2[i]-'A']++;
  }
  
  qsort(cnt1,26,sizeof(cnt1[0]),comp);
  qsort(cnt2,26,sizeof(cnt2[0]),comp);
  
      printf("%d %d\n",cnt1,cnt2);
  for(int i=0;i<26;i++)
  {
   if(cnt1[i]!=cnt2[i])
   {
   printf("NO\n");
   return 0;
      }
  }
   printf("YES\n");
 }

 return 0;
}

本代码还有C++版。

### K-Means 聚类算法详 #### 1. 原理概述 K-Means 是一种基于距离的无监督学习算法,其目标是最小化各簇内的平方误差之和(Sum of Squared Errors, SSE)。它通过迭代优化的方式寻找最佳的簇中心位置。然而,该算法对初始质心的选择非常敏感[^2]。 #### 2. 算法流程 以下是 K-Means 的基本工作流程: - 初始化 k 个簇中心。 - 将每个样本分配到最近的簇中心所属的簇。 - 更新每个簇的中心为当前簇中所有点的均值。 - 重复上述两步直到收敛条件满足(如簇中心不再变化或达到最大迭代次数)。 由于初始化阶段可能引入偏差,因此存在陷入局部最优的风险[^1]。 #### 3. 改进方案——二分 K-Means 为了缓传统 K-Means 对初值依赖性强的问题,提出了二分 K-Means 方法。此方法采用逐步分裂策略来构建最终分类结构:最初把整个数据集看作单一集群,在每轮循环里挑选使总 SSE 减少最多的那个子群再做进一步细分,如此继续下去直至预设数量完成分割操作为止。 #### 4. Python 实现示例 下面给出一段简单的Python代码用于演示如何利用 scikit-learn 库执行标准版以及改进后的版本: ```python from sklearn.cluster import KMeans, MiniBatchKMeans import numpy as np def perform_kmeans(data, num_clusters): """ 使用sklearn进行常规KMeans聚类 """ model = KMeans(n_clusters=num_clusters) labels = model.fit_predict(data) return labels, model.inertia_ def binary_split_kmeans(data, max_clusters): """ 执行二分KMeans聚类 """ current_num_clusters = 1 clusters = [data] while current_num_clusters < max_clusters: best_sse_reduction = None best_cluster_to_split = -1 for i in range(len(clusters)): cluster_data = clusters[i] # Apply standard KMeans with two centers on this subset. _, sse_before = perform_kmeans(cluster_data, 1) _, sse_after = perform_kmeans(cluster_data, 2) reduction = (sse_before - sse_after)/sse_before if not best_sse_reduction or reduction > best_sse_reduction: best_sse_reduction = reduction best_cluster_to_split = i # Split the identified cluster into two using regular KMeans(k=2). old_cluster = clusters.pop(best_cluster_to_split) km_model = KMeans(n_clusters=2).fit(old_cluster) new_clusters = [ old_cluster[km_model.labels_==j,:] for j in range(2)] clusters.extend(new_clusters) current_num_clusters += 1 final_labels = [] index_map = {} counter = 0 for c_idx,cluster in enumerate(clusters): size = len(cluster) label_val = c_idx + sum([len(v) for v in list(index_map.values())]) index_map[c_idx]=range(counter,label_val ) counter=label_val all_points=np.vstack(clusters) result=[None]*all_points.shape[0] for key,value_range in index_map.items(): for idx in value_range: result[idx]=key return result # Example usage: X = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]]) labels_standard, _ = perform_kmeans(X, 2) print("Standard KMeans Labels:", labels_standard) binary_labels = binary_split_kmeans(X, 2) print("Binary Split KMeans Labels:", binary_labels) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值