去掉数组重复元素 + 交换一串数组元素

本文探讨了改进排序算法和交换元素位置的方法,通过减少不必要的数组移动来提高效率。提出了利用新表进行元素筛选和倒置数组的技术,显著降低了时间复杂度。详细介绍了两种改进算法的原理和实现,包括如何通过倒置操作简化元素交换过程,适用于不同场景的通用解决方案。

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

1、已知整数数组a[n]中有重复的元素,试实现函数 void purge( int * a, int &n ); 该函数Post 条件为a[n] 中个元素相异。
 常规思路:对表中任一个元素a[i],令 j 从 i+1 到 n-1,将a[i]和a[j]进行比较,若相等,则从顺序表中删除该元素,然后从 j+1 到 n-1 的元素均向前移动一个位置。

 弊端: 在删除元素时引起的一连串的元素向前移动非常费时,而且在上述算法中"每发现一个和a[i]相同的元素, 就删除元素+移动数组的做法会使那些值和a[i]不同的元素重复多次移动操作。 时间度为 O(n*n)。

 改进:假设我们建一个新表,对原顺序表中每一个当前考察的数据元素,在"新表"中进行查找,如果有相同的则舍弃之,否则就插入到"新表"中。这样就省去了大量的移动操作,虽然外层循环还是 n, 时间复杂度也为 O(n*n),但操作步骤却大大减少了。而且,因为这里是“删除”操作,直接对原数组进行操作,所以那个我们假设的“新表”其实就是被操作的数组,只需要新建一个“指针”(这里为数组下标)即可。
 Code:
void purge( int *a, int & n ) 
{
 int k = -1;
 for( int i = 0; i<n; ++i ) 
 {
  int j = 0;
  while( j<=k && a[j] != a[i] )
   ++j;
  if( k==-1 || j>k )
  { ++k; a[k] = a[i]; }
 }
 n = k+1;
}

2、实现函数 void exchange( int *a, int p1, int n ) , 该函数把数组a[n] 的前 p1 个元素和 剩下的后 n-p1个元素互换位置。 比如原数组为 { 1, 2, 3, 4, 5, 6, 7 } ,执行 exchange( a, 3, 7 ) 后变为 { 4,5,6,7,1,2,3 }。
 常规思路: 把后面的最后一个数插到第一个,然后平移数组。依次到把后面元素全部放到新数组的前面。时间复杂度为 O( p1*(n-p1) ).
 改进: 为了消除平移数组的巨大消耗,考虑用倒置数组或倒置数组的一部分。导致能把后面一段整体移到前端,再对移到前端的那部分做倒置,又回复了原来的数序。所以可以通过三次倒置(1次全倒+2次部分倒)能达到目的。
 推广:同样的方法,可以让数组的任何两段互换位置。
 Code:
// 倒置从下标 p1 到 p2 的数组
void invert( int a[], int p1, int p2 )   
{
 int temp;
 for(int i =p1; i<=(p1+p2)/2; ++i )
 { temp = a[i]; a[i] = a[p2+p1-i]; a[p2+p1-i]=temp; }
}

void exchange( int a[], int p1, int n )
{
 if( p1>0 && p1<n) 
 {
 int p2 = n-p1;
 invert(a, 0, n-1);
 invert(a, 0, p2-1);
 invert(a, p2, n-1);
 }
}
 

<think>我们要使用指针数组对不等长的字符串进行排序。思路是:1.在主函数中定义一个二维字符数组来存储字符串(行数固定,列数足够大以容纳最长字符串)。2.定义一个指针数组,每个元素指向一个字符串(即二维数组的每一行)。3.将指针数组传递给排序函数,在排序函数中比较指针数组所指向的字符串,并根据比较结果交换指针数组中的指针(而不是交换字符串本身)。4.排序后,按指针数组的顺序输出字符串即可。注意:由于字符串长度不等,我们不能使用固定长度的数组指针(如char(*p)[20]),而是使用指针数组(char*p[]),每个元素是char*类型。参考引用[2]和引用[4]中的方法,我们使用指针数组来排序。以下代码示例将完成:-输入n个不等长字符串-使用指针数组进行排序(冒泡排序)-在主函数中输出排序后的字符串我们假设字符串的最大长度不超过80个字符,最多10个字符串。</think> 要使用指针数组对不等长的字符串进行排序并在主函数中输出结果,可以遵循以下步骤。这种方法避免了拷贝整串数据的开销,通过交换指针实现高效排序: ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LEN 80 // 单字符串最大长度 #define MAX_STR 10 // 最大字符串数量 // 字符串排序函数 void sortStrings(char *ptr[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { // 比较相邻字符串 if (strcmp(ptr[j], ptr[j + 1]) > 0) { // 交换指针而非字符串内容 char *temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } int main() { char strings[MAX_STR][MAX_LEN]; // 存储字符串的二维数组 char *ptr[MAX_STR]; // 指针数组 // 输入字符串数量 int n; printf("输入字符串数量(1-%d): ", MAX_STR); scanf("%d", &n); getchar(); // 消耗换行符 // 输入字符串并初始化指针 printf("输入%d个不等长字符串:\n", n); for (int i = 0; i < n; i++) { fgets(strings[i], MAX_LEN, stdin); // 移除换行符 strings[i][strcspn(strings[i], "\n")] = '\0'; ptr[i] = strings[i]; // 指针指向字符串 } // 排序字符串 sortStrings(ptr, n); // 输出结果 printf("\n排序后字符串:\n"); for (int i = 0; i < n; i++) { printf("%s\n", ptr[i]); } return 0; } ``` ### 关键点解析[^2][^4] 1. **指针数组结构** `char *ptr[MAX_STR]`创建指针数组,每个元素指向`strings`中的一行。排序只交换指针而非字符串内容,减少了数据拷贝开销$O(1)$ vs $O(n)$ 2. **输入处理优化** - 使用`fgets()`替代`scanf`确保安全输入$^1$ - `strcspn()`去除换行符,确保字符串比较准确 3. **排序算法** ```mermaid graph TD A[比较ptr[j]和ptr[j+1]] --> B{strcmp>0?} B -->|是| C[交换指针] B -->|否| D[继续比较] C --> D ``` 4. **内存布局优势** 原始字符串存储在连续内存中,排序通过调整指针顺序实现,避免: - 大字符串频繁拷贝 - 内存碎片问题 ### 执行示例 ``` 输入字符串数量(1-10): 3 输入3个不等长字符串: algorithm data structure 排序后字符串: algorithm data structure ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值