【问题标题】:Shift all the existing vowels in a Linked List at the end of the list in java在java中列表的末尾移动链接列表中的所有现有元音
【发布时间】:2012-12-22 00:35:05
【问题描述】:

我实际上是在尝试实现一个链表,该链表在最后使用 java.util 来移动列表中的所有现有元音。意思是,在每个节点中都给出了一个包含字符的列表(链接),我需要以这样一种方式分离它的节点,即所有具有元音的节点都通过保持原始顺序移动到链接列表的末尾。

输出应该是这样的:

original list: w->e->r->s->o->m->a->t
Output needed: w->r->s->m->t->a->e->o

我想在 java 中实现它。请让我知道优化的方法是什么(比如不使用任何额外的列表)。任何建议,帮助将不胜感激。

【问题讨论】:

  • 如果你想用Java,你为什么要添加C和C++标签?我已经删除了这些标签。如果您想要他们回来,请解释原因。
  • @Mark,我之前尝试在 c 中做,因此错误地添加了。
  • 除了元音最后,字母之间是否必须保持原来的相对顺序?
  • @Bohemian- 是的,信件之间必须保持原来的顺序。并且元音必须在列表末尾保持其原始顺序,无论它们在给定列表中的位置如何。

标签: java data-structures linked-list singly-linked-list


【解决方案1】:

试试

    LinkedList<Character> list = new LinkedList<>(Arrays.asList('w', 'e', 'r', 's', 'o', 'm', 'a', 't'));
    int n = list.size();
    for(int i = 0; i < n; i++) {
        char c = list.get(i);
        if ("aeiuoAEIUO".indexOf(c) != -1) {
            list.remove(i);
            list.add(c);
            n--;
        }
    }
    System.out.println(list);

输出

[w, r, s, m, t, e, o, a]

【讨论】:

  • 谢谢Evgeniy,你能告诉我如何保持列表末尾元音的原始顺序,而不管给定列表中的临时位置如何?有没有可能我可以在不创建任何额外列表的情况下做到这一点(用于优化)
  • 我喜欢这个,因为它可以就地洗牌,就像Queue
【解决方案2】:

你可以做这样的事情,但很可能有一种更有效的方法。

private LinkedList reOrder(LinkedList<Character> chars) {
    LinkedList<Character> temporary = new LinkedList<Character>();
    for(Character a: chars) {
        if(a=='a' || a=='e' || a=='i' ||
           a=='y' || a=='u' || a=='o') {
            temporary.add(a);
        }
    }
    chars.removeAll(temporary);
    chars.addAll(temporary);
    return chars;
}

【讨论】:

  • 仅供参考此代码将在chars.remove(a);ConcurrentModificationException 一起爆炸。使用 foreach 循环时不能修改集合。请改用 Iterator 和 Iterator.remove()
  • 这可能可以通过在 for 循环中将 chars 更改为 chars.copy() 来解决。
  • 谢谢 Lukas,您能否告诉我是否可以在不创建任何临时或额外链接列表的情况下执行此操作?有可能吗?
【解决方案3】:

我会定义一个自定义的Comparator 对象,然后使用Collections.sort 对列表进行排序。在这里,我定义了一个比较器,当用作排序参数时会将所有元音移到末尾:

class VowelSort implements Comparator<Character>
{

    private static boolean isVowel(Character c)
    {
        return "AEIOUaeiou".contains(c.toString());
    }

    public int compare(Character arg0, Character arg1)
    {
        final boolean vowel0 = isVowel(arg0), vowel1 = isVowel(arg1);

            //if neither of the characters are vowels, they are "equal" to the sorting algorithm
        if (!vowel0 && !vowel1) 
            {
            return 0;
        }

            //if they are both vowels, compare lexigraphically
        if (vowel0 && vowel1)
            {
            return arg0.compareTo(arg1);
        }

            //vowels are always "greater than" consonants
        if (vowel0 && !vowel1)
            {
            return 1;
        }

            //and obviously consonants are always "less than" vowels
        if (!vowel0 && vowel1)
            {
            return -1;
        }

        return 0; //this should never happen
    }
}

主要...

Collections.sort(chars,new VowelSort());

如果您也想对辅音进行排序,只需更改

//if neither of the characters are vowels, they are "equal" to the sorting algorithm
if (!vowel0 && !vowel1)
{
        return 0;
}

//compare consonants lexigraphically
if (!vowel0 && !vowel1)
{
        return arg0.compareTo(arg1);
}

【讨论】:

  • 谢谢 ValekHalfHeart 这真的很有帮助。 :)
【解决方案4】:

这实际上与语言无关,但这是一种方法:

遍历列表一次,如您所愿,创建一个新列表并从原始列表中删除您遇到的每个元音并将它们放入新列表中。

最后只需将新列表附加到原始列表。当您删除元音时,您会将所有元音移到列表的末尾。

【讨论】:

  • 非常感谢!你能告诉我我们如何准确地执行隔离吗?
  • 我不会为你写这个,但上面的答案应该会给你一个很好的起点,让你开始用 Java 编写它。如果您在这样做时遇到具体问题,请同时发布这些问题
  • 之所以让你帮我展示是因为,我已经通过创建两个名为辅音和元音的列表来做到这一点,然后将它们合并,我真的很好奇它可以在一个更优化的方式而不使用任何额外的列表?
【解决方案5】:

创建自己的抽象数据结构,可以将下面的内容存储为 char 数组。

char[] word = new char[] { 'f', 'o', 'o', 'b', 'a', 'r' };

char[] reordered = new char[word.length];

int vowel = word.length - 1;
int nonVowel = 0;
for (int i = 0; i < word.length; i++) {
    switch (word[i]) {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
        reordered[vowel] = word[i];
        vowel--;
        break;
    default:
        reordered[nonVowel] = word[i];
        nonVowel++;
        break;
    }
}

现在,非元音的顺序是正确的,但元音的顺序是相反的。根据您的用例,您可以反转元音子顺序或定义“get(position)”,然后返回:

if (position < nonVowel)
            return reordered[position];
        else
            return reordered[reordered.length - (position - vowel)];

【讨论】:

    猜你喜欢
    • 2014-02-23
    • 2021-10-01
    • 2016-06-16
    • 1970-01-01
    • 2011-06-22
    • 2017-07-10
    • 2018-06-22
    • 2018-09-06
    • 1970-01-01
    相关资源
    最近更新 更多