【问题标题】:Seperatiing vowels and consonents of Linked List in Java在Java中分离链表的元音和辅音
【发布时间】:2015-07-18 09:19:55
【问题描述】:

链表可以用以下结构表示:-

struct Node
{
char data;
struct Node* next;
};
struct Node
{
char data;
struct Node* next;
};class Node
{
public char data;
public Node next;
}class Node
{
public char data;
public Node next;
}

给你一个函数,

struct Node* ReArrangeVowelsAndConsonants(struct Node* head);struct Node* 

ReArrangeVowelsAndConsonants(struct Node* head);static Node 

ReArrangeVowelsAndConsonants(Node head);static Node 

ReArrangeVowelsAndConsonants(Node head);

指针“head”指向链表的开头。实现函数重新排列并返回相同的列表,使所有元音占据列表的前半部分,所有辅音占据后半部分。

注意:

  1. 不要创建新列表,修改现有列表。
  2. 元音和辅音的相对顺序不应相互改变。
  3. 您可以假设列表的长度是偶数,并且一半节点包含元音,另一半包含辅音。
  4. 如果列表为 NULL,则返回 NULL。

例子:

输入:
a -> k -> r -> i -> t -> e -> o -> m

输出:
a ->i -> e -> o -> k -> r -> t -> m

说明:
前半部分的辅音 k 和 r 移到后半部分,后半部分的元音 e 和 o 移到前半部分,保持相对顺序不变。

我的代码正确执行操作,但不满足注释中的第 2 点。当我用元音交换辅音时,我的输出中元素的相对顺序会发生变化。我的代码在下面....我只需要如何使我的代码也适用于这种情况。

import java.io.*;
import java.lang.*;
import java.util.*;
public class Node
{
    public char data;
    public Node next;
    public static Node rearrange(Node head)
    {
        Node start=new Node();
        Node curr=new Node();
        Node temp=new Node();
        start=curr=head;
        int begin=0;
        int flag=0;
        while(head.next!=null)
        { 
            if(head.data=='a'||head.data=='e'||head.data=='i'||head.data=='o'||head.data=='u')
            {      // no change
            }
            else
            {
                curr=head.next;
                do
                {
                     System.out.println("CURR "+curr.data+" HEAD "+head.data);
                    if(curr.data=='a'||curr.data=='e'||curr.data=='i'||curr.data=='o'||curr.data=='u')
                    {
                     temp.data=curr.data;
                     curr.data=head.data;
                     head.data=temp.data;
                     break;
                    }
                }while((curr=curr.next)!=null);
            }
            head=head.next;
        }

        while(start.next!=null)
        {
            System.out.print(start.data+"->");
            start=start.next;
        }
        System.out.print(start.data);
        return start;

    }
    public static void main(String args[])
    {
      Scanner s=new Scanner(System.in);
      int count=0;
      System.out.println("Enter the number of characters:");
      int length=s.nextInt();
      System.out.println("Enter the character seperated by ->");
      String inp=s.next();
      StringTokenizer st=new StringTokenizer(inp,"->");
      Node[] a=new Node[inp.length()];
      for(int i=0;st.hasMoreElements();i++)
      {
        a[i]=new Node();
        a[i].data=(st.nextToken().toString()).charAt(0);
        count++;
      }
      a[count-1].next=null;
      for(int i=0;i<(count-1);i++)
      {
        a[i].next=a[i+1];
      }
      Node start =new Node();
      start=rearrange(a[0]);
    }
}

【问题讨论】:

  • 问题定义有点不完整:当第一个元素是辅音时会发生什么?如果我们应该返回相同的头部,那么我们需要进行内容替换。但是如果返回一个不同的节点作为头部是可以的,我们可以有一个基于重新链接的解决方案。
  • 其实是在一次编码测试中出现的。我们只需要在函数中编写逻辑并返回head即可。我们可以只用另一个改变头部数据。正如您在“其他”条件“交换”中​​看到的那样,我在我的代码中做到了这一点。如果第一个元素是辅音并且我们在后面的字符串中有元音,我们需要将这些元音带到第一个。如果我们力求找到任何元音,我们可以返回头部。是澄清了还是??
  • 考虑输入:r->m->o->p->q->g->a 预期输出:o->a->r->m->p->q ->g 我的程序输出:o->a->r->p->q->g->m 这会产生问题,相对顺序会发生变化,我们需要得到 r->m->p- >q->g 但我得到 r->p->q->g->m
  • 但我的意思是,如果允许您返回不同的节点作为头部,那么重新链接而不是内容交换可能会更容易。问题是这是否允许。
  • 你是说,如果我们可以使用:temp=curr;当前=头;头=温度;对?? @RealSkeptic

标签: java list data-structures linked-list


【解决方案1】:

我认为这个练习使用链表而不是数组是有原因的。如果您被允许返回一个新的头,那么您可以使用重新排列节点本身的方法,而不是在现有节点之间交换数据。这种方法的好处是只需要遍历列表一次。

这个实现的想法是保留我们找到的最新元音的标记。如果我们找到另一个元音,我们将它从链中取出并放在现有的最新元音之后。例如:

a -> b -> c -> i -> x -> e

假设我们的latestVowel 引用引用了a 节点,并且我们当前到达了i 节点。我们这样做:

a -> i -> b -> c -> x -> e

所以a 之后的内容现在是i 之后的内容,而a 直接链接到i。

要正确删除和添加链接,最好在您要检查的项之前使用项。因此,如果您有curr,您将检查curr.next 以查看它是否是元音。如果是,很容易将其从链中删除,方法是将其next 分配给curr 的下一个。当然,您需要先将其添加到新位置,否则您可能会有悬空链。

这里是方法,每个部分用cmets来解释:

public static Node rearrangeVowelsAndConsonants(Node head) {
    Node newHead = head;
    Node latestVowel;
    Node curr = head;

    if (head == null) {
        return null;
    }

    // We need to discover the first vowel in the list. It is going to be
    // the returned head, and also the initial latestVowel.
    if (isVowel(head.data)) {
        // Easy: first element is a vowel. It will also be the new head
        // and the initial latestVowel;
        latestVowel = head;
    } else {
        // First element is not a vowel. Iterate through the list until we
        // find a vowel. Note that curr points to the element *before*
        // the element with the vowel.
        while (curr.next != null && !isVowel(curr.next.data)) {
            curr = curr.next;
        }
        // This is an edge case where there are only consonants.
        if (curr.next == null) {
            return head;
        }
        // Set the initial latestVowel and the new head to the vowel
        // item that we found. Relink the chain of consonants after
        // that vowel item:
        // old_head_consonant->consonant1->consonant2->vowel->rest_of_list becomes
        // vowel->old_head_consonant->consonant1->consonant2->rest_of_list
        latestVowel = newHead = curr.next;
        curr.next = curr.next.next;
        latestVowel.next = head;
    }

    // Now traverse the list. Curr is always the item *before* the one we are
    // checking, so that we can use it to re-link.
    while ( curr != null && curr.next != null ) {
        if (isVowel(curr.next.data)) {
            // The next discovered item is a vowel
            if (curr == latestVowel) {
                // If it comes directly after the previous vowel, we don't need
                // to move items around, just mark the new latestVowel and
                // advance curr.
                latestVowel = curr = curr.next;
            } else {
                // But if it comes after an intervening chain of consonants,
                // we need to chain the newly discovered vowel right after
                // the old vowel. Curr is not changed as after the re-linking
                // it will have a new next, that has not been checked yet,
                // and we always keep curr at one before the next to check.
                Node temp = latestVowel.next;   // Keep start of consonant chain
                latestVowel.next = curr.next;   // Chain in new vowel
                latestVowel = latestVowel.next; // Advance latestVowel
                curr.next = curr.next.next;     // Remove found vowel from previous place
                latestVowel.next = temp;        // Re-link the chain of consonants after lastestVowel.
            }
        } else {
            // No vowel in the next element, advance curr.
            curr = curr.next;
        }
    }
    return newHead;
}

【讨论】:

    【解决方案2】:

    您可以实现另一种排序算法。 如果您不是通过将元音与辅音交换来排序,而是通过将元音与它们的前一个元素(如果它是辅音)一个接一个地交换来排序并传递元音,那么您将对列表和元音之间的相对顺序进行排序和辅音不受影响。

    如果您不确定如何实现这样的排序算法,请查看冒泡排序:

    Bubble sort Wikipedia

    【讨论】:

    • 这是一个很好的方法..!!但是算法的复杂度会更多!!但是仍然要获得正确的输出,这种方法是好的。我会执行的!谢啦 !我应该想到排序技术! @Yindy
    【解决方案3】:
    // Here is the Correct Answer  after merging the previous answers. 
    // It works Correctly...!
    // Splitting Vowels And Consonants 
    
    import java.util.Scanner;
    import java.util.StringTokenizer;
    
    public class Node 
    {
        public char data;
        public Node next;
        public static Node rearrangeVowelsAndConsonants(Node head) {
            Node newHead = head;
            Node latestVowel;
            Node curr = head;
    
            if (head == null) {
                return null;
            }
    
    
            if (isVowel(head.data)) {
    
                latestVowel = head;
            } else {
    
                while (curr.next != null && !isVowel(curr.next.data)) {
                    curr = curr.next;
                }
    
                if (curr.next == null) {
                    return head;
                }
    
                latestVowel = newHead = curr.next;
                curr.next = curr.next.next;
                latestVowel.next = head;
            }
    
    
            while ( curr != null && curr.next != null ) {
                if (isVowel(curr.next.data)) {
    
                    if (curr == latestVowel) {
    
                        latestVowel = curr = curr.next;
                    } else {
    
                        Node temp = latestVowel.next;   
                        latestVowel.next = curr.next;   
                        latestVowel = latestVowel.next; 
                        curr.next = curr.next.next;    
                        latestVowel.next = temp;        
                    }
                } else {
    
                    curr = curr.next;
                }
            }
            return newHead;
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner s=new Scanner(System.in);
              int count=0;
              System.out.println("Enter the character seperated by ->");
              String inp=s.next();
              StringTokenizer st=new StringTokenizer(inp,"->");
              Node[] a=new Node[inp.length()];
              for(int i=0;st.hasMoreElements();i++)
              {
                a[i]=new Node();
                a[i].data=(st.nextToken().toString()).charAt(0);
                count++;
              }
              a[count-1].next=null;
              for(int i=0;i<(count-1);i++)
              {
                a[i].next=a[i+1];
              }
             Node start=rearrangeVowelsAndConsonants(a[0]);
            while(start.next!=null)
            {
                System.out.print(start.data+"->");
                start=start.next;
            }
            System.out.println(start.data);
            s.close();
        }
        public static boolean isVowel(char ch)
        {
            if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')
            {
                return true;
            }
            else
                return false;
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      相关资源
      最近更新 更多