插入字符,字符串仍有序 method 1

本文介绍了一个简单的字符插入排序算法实现,通过将一个字符插入到已排序的字符串中,保持字符串的有序状态。算法首先确定插入位置,然后从字符串末尾开始逐个元素向右移动,为新字符腾出空间,最后在正确位置插入字符。本文适用于初学者理解字符数组操作和排序逻辑。

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

 

有一个字符串,其元素已经按照从小到大顺序排列好,现在另外给一个字符c,请将该字符插入到串中,并使新串仍然有序。

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

int main()
{
	char a[1000],h;
	int i,c,b,j,n;
	scanf("%d",&n);
	while(n--)
	{
		b=0;
		c=0;
		scanf("%s ",&a);
		scanf("%c",&h);
		b=strlen(a);
		for(i=0;i<b;i++)
		{
			if(h<a[i])
			{
				c=i;// 保留要插入的位置
				break;
			}
		} 
		
		for(i=b-1;i>=c;i--)
		{
			a[i+1]=a[i]; //将插入元素以后的所有元素水平右移
		}
		a[c]=h;
		for(i=0;i<=b;i++)
		{
			printf("%c",a[i]);
		}
		printf("\n");

        if(h>=a[b-1]) // 当插入的元素比原有字符串每个元素都要大,放到最后
		{
			a[b]=h;//
			for(i=0;i<=b;i++)
			{
				printf("%c",a[i]);
			}
			printf("\n");
			continue; // 跳出这个循环,进入下一次循环
			
		}		
	}
	
	return 0;
}

eg.

input :abdef  c

output:abcdef

在 Java 中,当比较方法违反其契约时,会抛出 `Java comparison method violates general contract` 错误。这通常发生在使用自定义的 `Comparator` 或实现 `Comparable` 接口时,没有正确遵循比较契约的要求。解决此问题的关键在于确保比较逻辑满足以下条件: - **一致性**:如果两个对象在多次调用中比较结果相同,则应返回一致的结果。 - **反对称性**:如果 `a.compareTo(b)` 返回正值,则 `b.compareTo(a)` 应该返回负值。 - **传递性**:如果 `a.compareTo(b) > 0` 并且 `b.compareTo(c) > 0`,那么 `a.compareTo(c) > 0` 必须成立。 - **相等性**:如果 `a.compareTo(b) == 0`,则 `a.equals(b)` 应该为 `true`(除非 `equals()` 方法被修改)[^2]。 ### 常见错误示例 一个常见的错误是使用减法来实现比较逻辑,例如: ```java public int compareTo(Person other) { return this.age - other.age; } ``` 这种写法可能由于整数溢出导致不一致的结果。为了避免这种情况,可以使用 `Integer.compare()` 方法替代: ```java public int compareTo(Person other) { return Integer.compare(this.age, other.age); } ``` ### 自定义 Comparator 的编写规范 在编写自定义的 `Comparator` 时,确保逻辑清晰并避免依赖于非确定性的状态。例如,下面是一个安全的比较器实现: ```java Comparator<Person> byAge = (p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()); ``` ### equals() 和 hashCode() 的同步重写 如果类重写了 `compareTo()` 或 `equals()` 方法,则需要同步重写 `hashCode()` 方法以保持一致性。否则可能会引发不可预测的行为,尤其是在使用集合类时。例如: ```java @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Person)) return false; Person other = (Person) obj; return age == other.age && name.equals(other.name); } @Override public int hashCode() { return Objects.hash(name, age); } ``` ### 避免 Null 比较 在比较过程中,避免对 `null` 值进行直接操作,因为这可能导致 `NullPointerException`。可以在比较之前检查是否为 `null`,或者使用 `Objects.compare()` 等工具方法处理潜在的 `null` 值: ```java return Objects.compare(this.name, other.name, String::compareTo); ``` ### 使用 Red-Black Tree 实现的 TreeMap `TreeMap` 是基于红黑树实现的有序映射,它依赖于键的自然排序或提供的 `Comparator`。因此,在使用 `TreeMap` 时,确保键对象的比较逻辑符合契约要求非常重要。例如,当插入键值对时,`TreeMap` 内部会调用比较方法来维护顺序: ```java TreeMap<String, Integer> map = new TreeMap<>(); map.put("banana", 3); map.put("apple", 2); map.put("orange", 5); ``` 在这个例子中,字符串的自然排序决定了键的顺序。如果使用自定义类型作为键,则必须确保其 `compareTo()` 方法或外部提供的 `Comparator` 符合契约要求。 ### 总结 要修复 `Java comparison method violates general contract` 错误,需要仔细检查和调整比较逻辑,确保其满足所有契约要求。特别是要注意以下几点: - 避免整数溢出问题。 - 保证比较的一致性和传递性。 - 同步重写 `equals()` 和 `hashCode()`。 - 在自定义 `Comparator` 中避免不确定的状态。 通过这些措施,可以有效防止因比较方法违反契约而导致的异常问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值