中文排序问题

Lidew 2020-05-21 03:41:09
			string[] arr = { "视频", "试听" };
Array.Sort(arr);

中文的默认排序是按照发音的,为什么排序的结果却是 试听 在 视频 之前
...全文
832 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
Uranus.X 2020-05-26
  • 打赏
  • 举报
回复
Collator cmp = Collator.getInstance(Locale.CHINA);
String[] arr = { "视频", "试听", "视图", "使用" };
List<String> list = Arrays.asList(arr);
Collections.sort(list,cmp);
System.out.println(list);
Lidew 2020-05-25
  • 打赏
  • 举报
回复
谢谢各位,现在改为用数据库的排序,加了一个ID字段作为排序,然后C#这边也用ID进行排序,通过这样避免排序不一致的情况
丁劲犇 2020-05-24
  • 打赏
  • 举报
回复
和ascii.的十六进制大小有关。在80年代制定汉字标准时,因为存储空间是kb级别的,所以分一类字库,二类字库。一类常用字按拼音,二类按部首。因为二类字的读法很难,可能最初是为了输入法考虑。 这导致了按照汉字字节16进制排序,常用字按拼音在前,其他的靠后。最先是gb2312系列,包括gbk。后来unicode出来了,尤其是utf8排序可能稍有变化. 按拼音排序,需要拼音码表做哈西,而后读音相同的,按ascii自然顺序就是常用字在前了。
yysyysyys191501 2020-05-23
  • 打赏
  • 举报
回复
是的,这样子是可以的
Lidew 2020-05-23
  • 打赏
  • 举报
回复
引用 22 楼 weixin_46118443 的回复:
虽然'视'和'试'的拼音一样,但它们在按拼音排的字典中还是有先后的。
如果'视'和'试'可以比出大小,就可不用考虑后面的'频'和'听'。

是的,按理来说sql server和C#的中文发音排序都是遵循某种规范的,想了解这两者规范的不一致在哪
github_36000833 2020-05-22
  • 打赏
  • 举报
回复
引用 7 楼 正怒月神 的回复:
... 另外说一下: Array.Sort会因为比较器是Null或者 Default, 而内部调用 TrySZSort。我是不知道这个API的具体实现是什么样。 其他的比较器貌似也达不到你的要求。
Array.Sort字符串的时候,结果和Array.Sort(arr, StringComparer.CurrentCulture)的结果是一样的。 另外,如果要笔划排序,可以:
var zhCN拼音 = new CultureInfo(0x00804);// zhCN拼音.CompareInfo 等于 zh-CN
var zhCN笔划 = new CultureInfo(0x20804);// zhCN笔划.CompareInfo 等于 zh-CN_stroke
var strings =  new [] { "一", "二" };

foreach (var culture in new[] { zhCN拼音, zhCN笔划 })
{
    CultureInfo.CurrentCulture = culture;
    Array.Sort(strings);
    Console.WriteLine(string.Join(",", strings));
                
    // 输出
    // 二,一
    // 一,二
}
niebo_bar 2020-05-22
  • 打赏
  • 举报
回复
应该还是根据Unicode代码的顺序来进行排序的,可以参考一下汉字的Unicode编码来确定排序标准
github_36000833 2020-05-22
  • 打赏
  • 举报
回复
引用 2 楼 Lidew 的回复:
如果要按照拼音排序,只能自己重写比较的方法吗?
自己也写挺困难的。 目前dotnet排序,如果发现第一个字不一样,就不会麻烦比较后面的字符。对dotnet排序来说,"视"和"试"还是有大小的:
// i = 1, 说明:‘视’ 大于 '试'
var i = string.Compare("视", "试", new CultureInfo("zh-CN"), CompareOptions.None); 
下面实验,按第一个字分组的效果很明显,虽然第一个字的拼音是一样的。
CultureInfo.CurrentCulture = new CultureInfo("zh-CN");
string[] arr;

arr = new[] { "倚", "一", "衣" };
Array.Sort(arr);
Console.WriteLine(string.Join(",", arr)); // 输出:一,衣,倚

arr = new[] { "阿", "包"};
Array.Sort(arr);
Console.WriteLine(string.Join(",", arr)); // 输出:阿,包

arr = new[] { "倚阿", "倚包", "一阿", "一包", "衣阿", "衣包" };
Array.Sort(arr);
Console.WriteLine(string.Join(",", arr)); // 输出:一阿,一包,衣阿,衣包,倚阿,倚包
如果自己写,要自己判断是否不同字符的拼音一样,如果一样,接着判断随后字符。但是, 中文有多音字,要完全非常准确的判断,需要上下文知识,需要很好的‘人工’智能。 // 多音字词组例子,如果要准确的吧cang'ni排zang'ao在前面,就需要利用上下文来确认汉字的拼音。否则ao排在ni前面。 arr = new[] { "藏匿", "藏獒" }; Array.Sort(arr); Console.WriteLine(string.Join(",", arr)); // 输出:藏獒,藏匿
Lidew 2020-05-22
  • 打赏
  • 举报
回复
有没哪位知道怎样把C#的排序和数据库一致
正怒月神 2020-05-22
  • 打赏
  • 举报
回复
引用 11 楼 Lidew 的回复:
[quote=引用 10 楼 正怒月神 的回复:] [quote=引用 9 楼 Lidew 的回复:] 错了,应该是这样: 使用 视频 视图 试听 因为从数据库里边按照中文发音进行排序,出来是这样的结果,也想在C#的排序也能达到这个效果
抱歉,我没有看懂这个排序规则。。。 视图,为什么在试听前面?[/quote] 我也没搞清,它是根据sql server数据库排序得到的[/quote] 那就不知道了。我也想不出。
Lidew 2020-05-22
  • 打赏
  • 举报
回复
引用 10 楼 正怒月神 的回复:
[quote=引用 9 楼 Lidew 的回复:]
错了,应该是这样:
使用
视频
视图
试听
因为从数据库里边按照中文发音进行排序,出来是这样的结果,也想在C#的排序也能达到这个效果

抱歉,我没有看懂这个排序规则。。。
视图,为什么在试听前面?[/quote]
我也没搞清,它是根据sql server数据库排序得到的
正怒月神 2020-05-22
  • 打赏
  • 举报
回复
引用 9 楼 Lidew 的回复:
错了,应该是这样: 使用 视频 视图 试听 因为从数据库里边按照中文发音进行排序,出来是这样的结果,也想在C#的排序也能达到这个效果
抱歉,我没有看懂这个排序规则。。。 视图,为什么在试听前面?
Lidew 2020-05-22
  • 打赏
  • 举报
回复
错了,应该是这样:
使用
视频
视图
试听
因为从数据库里边按照中文发音进行排序,出来是这样的结果,也想在C#的排序也能达到这个效果
Lidew 2020-05-22
  • 打赏
  • 举报
回复
按照拼音进行排序,输出要达到:使用,视频,试听,视图,这样的效果
正怒月神 2020-05-22
  • 打赏
  • 举报
回复
引用 6 楼 Lidew 的回复:
[quote=引用 5 楼 正怒月神 的回复:]
public static void Main(string[] args)
        {
            string[] arr = { "视频", "试听", "视图", "使用" };

            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                Console.WriteLine("[{0}]:\t{1}", i, arr.GetValue(i));

            Console.ReadLine();
        }
麻烦看一下要求[/quote] 不知道哪里没有符合要求了? 只要你把for里面的输出,改成添加到新的数组,就好了。
string[] arr = { "视频", "试听", "视图", "使用" };
            string[] arr1 = new string[arr.Length];
            
            for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
                //Console.WriteLine("[{0}]:\t{1}", i, arr.GetValue(i));
                arr1[i] = arr.GetValue(i).ToString();

            Console.ReadLine();
另外说一下: Array.Sort会因为比较器是Null或者 Default, 而内部调用 TrySZSort。我是不知道这个API的具体实现是什么样。 其他的比较器貌似也达不到你的要求。
Lidew 2020-05-22
  • 打赏
  • 举报
回复
引用 5 楼 正怒月神 的回复:
public static void Main(string[] args)
{
string[] arr = { "视频", "试听", "视图", "使用" };

for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
Console.WriteLine("[{0}]:\t{1}", i, arr.GetValue(i));

Console.ReadLine();
}

麻烦看一下要求
weixin_46118443 2020-05-22
  • 打赏
  • 举报
回复
虽然'视'和'试'的拼音一样,但它们在按拼音排的字典中还是有先后的。 如果'视'和'试'可以比出大小,就可不用考虑后面的'频'和'听'。
qq_37629876 2020-05-22
  • 打赏
  • 举报
回复
视频是名词,试听是动词,英文里名词一般排在动词前。或许吧。。。
正怒月神 2020-05-22
  • 打赏
  • 举报
回复
引用 16 楼 github_36000833 的回复:
[quote=引用 7 楼 正怒月神 的回复:] ... 另外说一下: Array.Sort会因为比较器是Null或者 Default, 而内部调用 TrySZSort。我是不知道这个API的具体实现是什么样。 其他的比较器貌似也达不到你的要求。
Array.Sort字符串的时候,结果和Array.Sort(arr, StringComparer.CurrentCulture)的结果是一样的。 另外,如果要笔划排序,可以:
var zhCN拼音 = new CultureInfo(0x00804);// zhCN拼音.CompareInfo 等于 zh-CN
var zhCN笔划 = new CultureInfo(0x20804);// zhCN笔划.CompareInfo 等于 zh-CN_stroke
var strings =  new [] { "一", "二" };

foreach (var culture in new[] { zhCN拼音, zhCN笔划 })
{
    CultureInfo.CurrentCulture = culture;
    Array.Sort(strings);
    Console.WriteLine(string.Join(",", strings));
                
    // 输出
    // 二,一
    // 一,二
}
[/quote] 单单从源码上来说,Array.Sort(arr)和Array.Sort<T>(arr)的重载并没有传入Comparer。 而是一个null值。 不过内部的TrySZSort有没有操作,我不得而知。 只能说,光从结果上来看,的确和Array.Sort(arr, StringComparer.CurrentCulture)一样。
L星星火 2020-05-22
  • 打赏
  • 举报
回复
把字符转成gbk,然后再排序
加载更多回复(5)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧