Ke Tian
Ke Tian

Reputation: 93

Java: Find the longest sequential same character array

I am a new guy to java. I want to find the longest sequential same character array in a input character arrays. For example,this character array bddfDDDffkl, the longest is DDD, and this one: rttttDDddjkl, the longest is tttt. I use the following code to deal with this problem. But, I want to improve my code, For example, if there are two same length arrays (for example rtttgHHH, there are two longest: ttt and HHH), how to solve this problem?

Thanks in advance.

My following code:

public class SeqSameChar {
public static void main (String[] args) {
   int subLength = 0;
   Scanner sc = new Scanner(System.in);
   String[] num = null;
   num = sc.nextLine().split(" ");
   String[] number = new String[num.length];

   for(int i = 0; i< number.length;i++) {
       number[i] = String.valueOf(num[i]);
   }

   subLength =length(number,num.length);  
   System.out.println(subLength);

   for(int i = index; i < index+subLength; i++) {
       System.out.print(number[i]);
   }

   System.out.println(c==c1); 
 }


   public static int index;  
      //to calculate the longest contiguous increasing sequence  
       public static int length(String[] A,int size){  
       if(size<=0)return 0;  
       int res=1;  
       int current=1;  
       for(int i=1;i<size;i++){  
           if(A[i].equals(A[i-1])){  
               current++;  
           }  
           else{  
               if(current>res){  
                   index=i-current;  
                   res=current;  
               }  
               current=1;  
           }  
       }  
      return res;      
     }      
   }

Upvotes: 1

Views: 2094

Answers (2)

pangiole
pangiole

Reputation: 991

I'll give you a Scala implementation for that problem.

Here it is the automatic test (in BDD style with ScalaTest)

import org.scalatest._
class RichStringSpec extends FlatSpec with MustMatchers {
  "A rich string" should "find the longest run of consecutive characters" in {
    import Example._
    "abceedd".longestRun mustBe Set("ee", "dd")
    "aeebceeedd".longestRun mustBe Set("eee")
    "aaaaaaa".longestRun mustBe Set("aaaaaaa")
    "abcdefgh".longestRun mustBe empty
  }
}

Following is the imperative style implementation, with nested loops and mutable variables as you would normally choose to do in Java or C++:

object Example {
  implicit class RichString(string: String) {
    def longestRun: Set[String] = {
      val chunks = mutable.Set.empty[String]
      val ilen = string.length
      var gmax = 0
      for ((ch, curr) <- string.zipWithIndex) {
        val chunk = mutable.ListBuffer(ch)
        var next = curr + 1
        while (next < ilen && string(next) == ch) {
          chunk += string(next)
          next = next + 1
        }
        gmax = chunk.length max gmax
        if (gmax > 1) chunks += chunk.mkString
      }
      chunks.toSet.filter( _.length == gmax )
    }
  }
}

Following is a functional-style implementation, hence no variables, no loops but tail recursion with result accumulators and pattern matching to compare each character with the next one (Crazy! Isn't it?):

object Example {
  implicit class RichString(string: String) {
    def longestRun: Set[String] = {
      def recurse(chars: String, chunk: mutable.ListBuffer[Char], chunks: mutable.Set[String]): Set[String] = {
        chars.toList match {
          case List(x, y, _*) if (x == y) =>
            recurse(
              chars.tail, 
              if (chunk.isEmpty) chunk ++= List(x, y) else chunk += y, 
              chunks
            )
          case Nil =>
            // terminate recursion
            chunks.toSet
          case _ => // x != y
            recurse(
              chars.tail,
              chunk = mutable.ListBuffer(), 
              chunks += chunk.mkString
            )
        }
      }
      val chunks = recurse(string, mutable.ListBuffer(), mutable.Set.empty[String])
      val max = chunks.map(_.length).max
      if (max > 0) chunks.filter( _.length == max ) else Set()
    }
  }
}

For example, for the given "aeebceeedd" string, both implementations above will build the following set of chunks (repeating characters)

Set("ee", "eee", "dd")

and they will filter those chunks having the maximum length (resulting "eee").

Upvotes: 0

burglarhobbit
burglarhobbit

Reputation: 2291

This algorithm will work perfectly fine for what you want to develop:

Before that, let me make it clear that if you want to check repeatitions of 2 different characters same number of times, you have to run a for loop in reverse to identify the 2nd character. So if the 2nd character is not same as the first one identified, and also if it's number of repeatitions are the same, you print both the characters or else, just print the single character you find at the first for loop because both the characters are going to be same.

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);
    System.out.println("Enter String 1: ");
    String A1 = sc.nextLine();

    MaxRepeat(A1);
}

public static void MaxRepeat(String A) {
    int count = 1;
    int max1 = 1;
    char mostrepeated1 = ' ';
    for(int i = 0; i < A.length()-1;i++) {
        char number = A.charAt(i);

        if(number == A.charAt(i+1)) {
            count++;
            if(count>max1) {
                max1 = count;
                mostrepeated1 = number;
            }
            continue;
        }
            count = 1;
    }

    count = 1;
    int max2 = 1;
    char mostrepeated2 = ' ';
    for(int i = A.length()-1; i>0; i--) {
        char number = A.charAt(i);

        if(number == A.charAt(i-1)) {
            count++;
            if(count>max2) {
                max2 = count;
                mostrepeated2 = number;
            }
            continue;
        }
            count = 1;
    }

    if((max1==max2) && (mostrepeated1==mostrepeated2)) {
        System.out.println("Most Consecutively repeated character is: " + mostrepeated1 + " and is repeated " + max1 + " times.");
    }

    else if((max1==max2) && (mostrepeated1!=mostrepeated2)) {
        System.out.println("Most continously repeated characters are: " + mostrepeated1 + " and " + mostrepeated2 + " and they are repeated " + max1 + " times");
    }
}

Upvotes: 3

Related Questions