I'm doing an assignment and I am done. This is a simple program that prints out pyramids of chars. However, I can't figure out why the program prints a newline when I never specified it with some input, even if it's meant to: https://i.imgur.com/gPs5oC5.png
Why do I have to have an extra newline when printing the pyramid upside down? Where is the newline printed?
import java.util.Scanner;
public class Test23 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean state = true;
String messageL = "Length: ";
String messageD = "Position: ";
String messageS = "Shutdown!";
while(state) {
int limit = 0;
int degree;
System.out.print(messageL);
int length = input.nextInt();
while ((length < 1 && length == -1) || length > 26) {
if (length == -1 ) {
System.out.println(messageS + "\n");
state = false;
break;
} else {
System.out.print(messageL);
length = input.nextInt();
}
}
if (!state)
break;
System.out.print(messageD);
degree = input.nextInt();
while((degree > 1) || (degree < 0)) {
System.out.print(messageD);
degree = input.nextInt();
}
if (degree == 0)
//No newline is needed here for some reason.
length++;
else if (degree == 1)
limit = length;
//New line here for the pyramids to print symmetrically.
//System.out.println("");
for (int i = 0; i < length; ++i) {
for (int counter = 0; counter < limit; counter++) {
char letter = (char)(counter + 'A');
System.out.print(letter);
}
if (degree == 0)
limit++;
else if (degree == 1)
limit--;
System.out.println("");
}
System.out.println("");
}
}
}
Small java program prints invisible newline?
In your program the last System.out.println(""); causes an extra line at the end of your program, i.e while(state) is true at the end, So either you comment the print statement or make your state=false at end.
while(state) {
...
System.out.println("");
}
The most inner loop won't run if the input is 0. limit will be 0, and hence the loop condition is false. As of this it will print en empty line, proceeding to add 1 too limit and then print chars.
for (int i = 0; i < length; ++i) {
for (int counter = 0; counter < limit; counter++) {
char letter = (char)(counter + 'A');
So trying to create a method which goes through a string and checks each char for vowels.
However when it reaches the end and does a forward check for the char. i get a strings out of bound exception. i tried adding a check for whitespace for the char ahead but still get the exception.
for (char i = 0; i < buffer.length; i++) {
if (isVowel(key.charAt(i + 1)) && !Character.isWhitespace(key.charAt(i + 1)) {
buffer[i] = key.charAt(i);
} else {
break;
}
}
Create the buffer for a correct size like
char[] keyChar = key.toCharArray();
char[] buffer = new char[keyChar.length]; //same size
Then, iterate the key, not the buffer
for(int i = 0; i < keyChar.length -1; ++i)
And don't go to the end since you use [i + 1] in the logic.
Note that this will ignore the last character, you have to see if you want that last character or not in the buffer. If so, you will need to add it (without your check on the next one obviously)
for (char i = 0; i < buffer.length-1; i++) {
if (isVowel(key.charAt(i + 1)) && !key.charAt(i + 1) && !Character.isWhitespace(key.charAt(i + 1)) {
buffer[i] = key.charAt(i);
} else {
break;
}
}
I am trying to compress a string by turning it in to letters and numbers. Example:
INPUT: AAAAbbWWWW
OUTPUT: A4-b2-W4
Here is the problem I am running in to:
When I run it with the query "aaaaaaa", I get "a7".
When I run it with the query "aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbb", I get "a12-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2".
My code is
List<Character> chars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
List<String> bits = new ArrayList<String>();
for (int i = 0; i < chars.size(); i++) {
char toMatch = chars.get(i);
int matching = 1;
for (int dontuse = i; dontuse < chars.size(); dontuse++) {
int x = dontuse + 1;
if (x >= chars.size()) {
continue;
}
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching++;
}
}
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
}
String compressed = "";
for (int y = 0; y < bits.size(); y++) {
if (y == (bits.size() - 1)) {
compressed += bits.get(y);
} else {
compressed += bits.get(y) + "-";
}
}
return compressed;
Can anyone tell me how to stop it from only counting to two in every segment but the first?
A simple algorithm for your problem would be the following:
private static String compress(String str) {
StringBuilder compressed = new StringBuilder();
int i = 0;
while (i < str.length()) {
int length = 1;
while (i < str.length() - 1 && str.charAt(i) == str.charAt(i+1)) {
length++;
i++;
}
compressed.append(str.charAt(i)).append(length).append('-');
i++;
}
return compressed.deleteCharAt(compressed.length() - 1).toString();
}
It goes like this: while the character of the input String at index i is the same as the following character, we increment a length. As a result, length is then equal to the number of following characters that are the same.
When we hit a different character, we stop the loop, store the current character and its length, and repeat all this again for the next character.
Note that this algorithm will "compress" the String b into b1. You did not specify how it should behave on such Strings. If you don't want to this, you can simply add a check on length before it is appended to the current compressed String.
Alright, I fixed it. Here is what I did:
List<Character> chars = new ArrayList<Character>();
List<Character> oChars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
for (char c : chars) {
if (!oChars.contains(c)) {
oChars.add(c);
}
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < chars.size(); i++) {
try {
map.put(chars.get(i), map.get(chars.get(i)) + 1);
} catch (NullPointerException ex) {
map.put(chars.get(i), 1);
}
}
String compressed = "";
for (char c : oChars) {
int amount = map.get(c);
compressed += c + "" + amount + "-";
}
StringBuilder b = new StringBuilder(compressed);
b.replace(compressed.lastIndexOf("-"), compressed.lastIndexOf("-") + 1, "" );
compressed = b.toString();
return compressed;
Well, your logic doesn't really work. In fact, it's pretty hard to understand what you are trying to do here.
The place where you add to bits is the important part, because at the end you basically display what's in bits. So let's look at that part.
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
So it's important to see where you change the matching.
The first loop runs fine verifying against the a. But your problem is in this condition:
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching is 1 at the beginning of the inner loop. So as soon as you are into ranges of i that are beyond 0 and 1, x - 1 is not going to be equal to matching, and that means that matching will not change, it will stay at 1.
So except your first character, you'll never get a correct number in matching, because it will never be incremented. There is no point in comparing a running index to a count.
This code supposed to output the longest run on which a character in a string has a consecutive runs of itself. Though the problem is that it outputs: 8 (which should be 5 instead). I just would like to ask what seems to be the problem regarding this code.
public class Sample {
public static void main(String[] args) {
String setofletters = "aaakkcccccczz"; /* 15 */
int output = runLongestIndex(setofletters);
System.out.println("Longest run that first appeared in index:" + output);
}
public static int runLongestIndex(String setofletters) {
int ctr = 0;
int ctrstor = 0;
int ii = 0;
int output = 0;
// loops until the last character in the string
for (int i = 0; i < setofletters.length() - 1; i++) {
// checks if the letter is the same to the next
if (setofletters.charAt(i) == setofletters.charAt(i++)) {
ctr++;
ii = i++;
// loops until the letter in the index is no longer equal
while (setofletters.charAt(i) == setofletters.charAt(ii)) {
ii++;
ctr++;
}
if (ctr > ctrstor) {
output = i;
}
// storing purposes
ctrstor = ctr;
}
// resets the counter
ctr = 0;
}
return output;
}
}
UPDATE Sorry, I misunderstood your question a bit, you need to make the following changes in your code to make it work.(lines with comments)
public static int runLongestIndex(String setofletters){
int ctr = 1; // every character is repeated at least once, so you should initialize it to 1, not 0
int ctrstor = 0;
int ii = 0;
int output = 0;
for (int i = 0; i < setofletters.length() - 1; i++) {
if (i < setofletters.length() - 1 && setofletters.charAt(i) == setofletters.charAt(i+1)) { // i++ is not same as i+1
ctr++;
ii = i+1; // i++ is not same as i+1
while (setofletters.charAt(i) == setofletters.charAt(ii)) {
ii++;
ctr++;
}
if (ctr > ctrstor) {
output = i;
}
ctrstor = ctr;
}
ctr = 1; // for the same reason I mentioned above
}
return output;
}
EDIT : the easiest way to write your code is :
public static int runLongestIndex(String setofletters){
int ctr = 1;
int output = 0;
int j=0;
for(int i=0; i<setofletters.length()-1;i++){
j=i;
while(i <setofletters.length()-1 && setofletters.charAt(i)==setofletters.charAt(i+1)){
i++;
ctr++;
}
if(ctr>output){
output=j;
}
ctr = 1;
}
return output;
}
Why are you assigning i to output? You should assign ctr to output.
change
if(ctr>ctrstor){
output=i;
}
to
if(ctr>ctrstor){
output=ctr;
}
and also I think you should change
if(setofletters.charAt(i)==setofletters.charAt(i++))
to
if(i<setofletters.length()-1 && setofletters.charAt(i)==setofletters.charAt(i+1)){
and you should intialize ctr to 1 but not 0 because every character is repeated at least once.
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").
This code should work for any length of string sequence.
public class LongestStringSequqnce {
static String myString = "aaaabbbbcccchhhhiiiiibbbbbbbbbccccccc";
static int largestSequence = 0;
static char longestChar = '\0';
public static void main(String args[]) {
int currentSequence = 1;
char current = '\0';
char next = '\0';
for (int i = 0; i < myString.length() - 1; i++) {
current = myString.charAt(i);
next = myString.charAt(i + 1);
// If character's are in sequence , increase the counter
if (current == next) {
currentSequence += 1;
} else {
if (currentSequence > largestSequence) { // When sequence is
// completed, check if
// it is longest
largestSequence = currentSequence;
longestChar = current;
}
currentSequence = 1; // re-initialize counter
}
}
if (currentSequence > largestSequence) { // Check if last string
// sequence is longest
largestSequence = currentSequence;
longestChar = current;
}
System.out.println("Longest character sequence is of character "
+ longestChar + " and is " + largestSequence + " long");
}
}
Source : http://www.5balloons.info/program-java-code-to-find-longest-character-sequence-in-a-random-string/
if(ctr>ctrstor){
output=i;
}
//storing purposes
ctrstor=ctr;
This looks like the problem. So if you find 8 consecutive characters, it will set output to 8, and proceed. The next time thru, it finds 3 consecutive characters, so doesn't set output, but sets ctrstor. Next time thru it finds 4 consecutive characters, and this will set output to 4
There are few traps in the code that your logic felt in:
Code incorrectly assumes that there is always next character to compare current one.
This fails for string like "a" or the last character in any string.
Code does not store the max count of characters but only the max index (i).
MaxCount is needed to compare the next chars sequence size.
Loop for and loop while repeat the same subset of characters.
Also variable name style makes it harder to understand the code.
After correcting above
public static int runLongestIndex(String setofletters) {
int maxCount = 0;
int maxIndex = 0;
// loops each character in the string
for (int i = 0; i < setofletters.length() - 1; ) {
// new char sequence starts here
char currChar = setofletters.charAt(i);
int count = 1;
int index = i;
while ( (index < setofletters.length() - 1) &&
(currChar == setofletters.charAt(++index)) ) {
count++;
}
if (count > maxCount) {
maxIndex = i;
maxCount = count;
}
i = index;
}
return maxIndex;
}
See Java DEMO
I think you don't need an internal loop:
public static int runLongestIndex(String setofletters) {
if (setofletters == null || setofletters.isEmpty()) {
return -1;
}
int cnt = 1;
char prevC = setofletters.charAt(0);
int maxCnt = 1;
//char maxC = prevC;
int maxRunIdx = 0;
int curRunIdx = 0;
for (int i = 1; i < setofletters.length(); i++){
final char c = setofletters.charAt(i);
if (prevC == c) {
cnt++;
} else {
if (cnt > maxCnt) {
maxCnt = cnt;
//maxC = prevC;
maxRunIdx = curRunIdx;
}
cnt = 1;
curRunIdx = i;
}
prevC = c;
}
if (setofletters.charAt(setofletters.length() - 1) == prevC) {
if (cnt > maxCnt) {
//maxC = prevC;
maxCnt = cnt;
maxRunIdx = curRunIdx;
}
}
return maxRunIdx;
}
and this code:
System.out.println(runLongestIndex("aaakkcccccczz"));
gives you
5
This is how a "colleague" of mine is understanding to write readable code in order to solve this problem, even if this is working :)
public static int count (String str) {
int i = 0;
while(i < str.length()-1 && str.charAt(i)==str.charAt(i+1))
i ++;
return ++i;
}
public static int getLongestIndex(String str){
int output = 0;
for(int i=0, cnt = 1, counter = 0 ; i<str.length() - 1;i += cnt, cnt = count(str.substring(i)), output = (counter = (cnt > counter ? cnt : counter)) == cnt ? i : output);
return output;
}
int indexOfLongestRun(String str) {
char[] ar = str.toCharArray();
int longestRun = 0;
int lastLongestRun = 0;
int index = 0;
for(int i = ar.length-1; i>0; i--){
if(ar[i] == ar[i-1]){
longestRun++;
}else{
if(longestRun > lastLongestRun){
lastLongestRun = longestRun;
longestRun = 0;
index = i;
}
}
}
return index;
Well, the solution a bit depends on the additional requirements. Here is the code which returns the FIRST longest sequence of a repeated character int the given string, meaning if you have a second sequence with the same length you never get it out :(. But still, this is a simple and clear solution here, so good news - it works! :)
string = 'abbbccddddddddeehhhfffzzzzzzzzdddvyy'
longest_sequence = ''
for i in range(len(string)):
is_sequence = True
ch_sequence = ''
while is_sequence:
ch_sequence += string[i]
if i+1 < len(string) and string[i]==string[i+1]:
i += 1
else:
is_sequence = False
if len(ch_sequence) > len(longest_sequence):
longest_sequence = ch_sequence
print (longest_sequence)
#Paolo Angioletti already provided an answer using Scala, but it's more complicated than it needs to be. The idea is not very different from Run-length encoding. Time complexity O(n).
def longestConsecutive(s: String): (Char, Int) = {
Iterator.iterate(('\u0000', 0, 0)) { case (ch, longestRun, i) =>
val run = (i until s.length)
.takeWhile(s(_) == s(i))
.size
if (run > longestRun) (s(i), run, i + run)
else (ch, longestRun, i + run)
}
.dropWhile(i => s.isDefinedAt(i._3))
.take(1)
.map(x => (x._1, x._2))
.next()
}
Tested with:
("s", "ch", "n")
----------------
("", '\u0000', 0),
("a", 'a', 1),
("aabcddbbbea", 'b', 3),
("abcddbbb", 'b', 3),
("cbccca", 'c', 3)
#include <iostream>
#include<algorithm>
using namespace std;
int main() {
string s="abbcccccbbffffffffff";
//cin>>s;
int count=1;
int maxcount=1;
int start=0;
int ps=0;
for (int i=0;i<s.size()-1;i++)
{
if(s.at(i)==s.at(i+1))
{
count +=1;
maxcount=max(maxcount,count);
}
else
{
ps=max(ps,start+count);
count =1;
start=i;
}
}
for(int i=1;i<=maxcount;i++)
{
cout<<s.at(i+ps);
}
// your code goes here
return 0;
}
This is the simplest I can think of and it will print the number of the longest sequenced identical characters in a one line string.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
scanner.close();
int count = 0;
int curCount = 1;
for (int i = 0; i < s.length() -1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) {
curCount++;
if (curCount > count) {
count = curCount;
}
}else {
if (curCount > count) {
count = curCount;
}
curCount = 1;
}
}
System.out.println(count);
}
String s="101010101010";
String sub=""; //substring
int k=2;
package coreJava;
import java.util.Scanner;
public class substring {
public static void main(String args[])
{
String string, sub;
int k, c, i;
Scanner in = new Scanner(System.in);
System.out.println("Enter a string to print it's all substrings");
string = in.nextLine();
i = string.length();
System.out.println("Substrings of \""+string+"\" are :-");
for( c = 0 ; c < i ; c++ )
{
for( k = 1 ; k <= i - c ; k++ )
{
sub = string.substring(c, c+k);
System.out.println(sub);
}
}
}
}
take a binary string s="1010011010"; //etc
take one variable k=2;
take another variable i; //which is the length of the sub string(i>k)
now i want to find sub string of the above string, in such a way that if k=2,the number of 1's in sub string must be 2,if k=3,the number of 1's in substring must be 3 and so on...
Output should be like this:
string s="1010011010"
Enter value of k=2;
Enter length of substring i=3;
substring= 101 110 101 011
Create a "window" the length of your desired substrings which you move along the string, maintaining a count of the number of 1s in your current window. Each iteration you move the window along one, testing the next character outside the current window, the first character in the current window and updating the count accordingly. During each iteration, if your count is equal to the desired length, print the substring from the current window.
public class Substring {
public static void main(String[] args) {
String str = "1010011010";
int k = 2;
int i = 3;
printAllSubstrings(str, i, k);
}
private static void printAllSubstrings(String str, int substringLength, int numberOfOnes) {
// start index of the current window
int startIndex = 0;
// count of 1s in current window
int count = 0;
// count 1s in the first i characters
for (int a = 0; a < substringLength; a++) {
if (str.charAt(a) == '1') {
count++;
}
}
while (startIndex < str.length() - substringLength + 1) {
if (count == numberOfOnes) {
System.out.print(str.substring(startIndex, startIndex + substringLength));
System.out.print(" ");
}
// Test next bit, which will be inside the window next iteration
if (str.length() > startIndex + substringLength && str.charAt(startIndex + substringLength) == '1') {
count ++;
}
// Test the starting bit, which will be outside the window next iteration
if (str.charAt(startIndex) == '1') {
count --;
}
startIndex++;
}
}
}
This outputs:
101 011 110 101
Iterate over the characters and count the number of one's. If the counter reaches the desired number, stop iterating and take the substring from index zero to where you got.
String str = "010101001010";
int count = 0;
int k = 2;
int i = 0;
for (; i < str.length() && count < k; ++i)
{
if (str.charAt(i) == '1') count++;
}
You could use regular expressions:
public class BinaryString {
public static void main(String[] args) {
String binary = "11000001101110";
int count = 3;
String regEx = "1{" + count + "}";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(binary);
if (m.find()) {
int startIndex = m.start();
System.out.println("MATCH (#index " + startIndex + "): "+ m.group());
} else {
System.out.println("NO MATCH!");
}
}
}
OUTPUT
MATCH (#index 10): 111