Adding dots into a system.out.println - java

well basically I have a line thats has a finial in of 40,
if a add 2 words that are 10 letters each long that leaves me with 20 spaces
thouse 20 spaces should be filled with dots ...... for example
hello................................you
or
stack...........................overflow
now I have the code working fine, I just have no idea on how to please this in a system.out.println so that the result is printed to the console.
I was thinking of using a whileloop to print the dots one at a time, after testing how many number of dots there should be once bother words are entered.
At the moment I have this which clearly doesn't work
{
System.out.println (word1 + ".." + word2);
while (wordlegnth1 + wordlegnth2 < LINELENGTH)
{
System.out.println (word1 + "." + word2);
wordlegnth1++;
}

final int LINE_LENGTH = 40;
String word1 = ...;
String word2 = ...;
StringBuilder sb = new StringBuilder(LINE_LENGTH);
sb.append(word1);
for (int i = 0; i + word1.length() + word2.length() < LINE_LENGTH; i++) {
sb.append(".");
}
sb.append(word2);
System.out.println(sb.toString());
Note: the use of StringBuilder is to avoid performance penalty due to String immutability

/**
* Formats a given string to 40 characters by prefixing it with word1 and
* suffixing it with word2 and using dots in the middle to make length of final
* string = 40.
* If string will not fit in 40 characters, -1 is returned, otherwise 0 is
* returned.
*
* #param word1 the first word
* #param word2 the second word
* #return 0 if string will fit in 40 characters, -1 otherwise
*/
public static int formatString(String word1, String word2) {
final int LINELENGTH = 40;
// determine how many dots we need
int diff = LINELENGTH - (word1.length() + word2.length());
if (diff < 0) {
// it's too big
System.out.println("string is too big to fit");
return -1;
}
// add the dots
StringBuilder dots = new StringBuilder();
for (int i = 0; i < diff; ++i) {
dots.append(".");
}
// build the final result
String result = word1 + dots.toString() + word2;
System.out.println(result);
return 0;
}
public static void main(String[] args) throws Throwable {
formatString("stack", "overflow");
String str = "";
for (int i = 0; i < 21; ++i) {
str += "a";
}
formatString(str, str);
}
Output:
stack...........................overflow
string is too big to fit

Why not start with something like:
int lengthA = word1.length();
int lengthB = word2.length();
int required = LINE_LENGHT - (lengthA + lengthB);
for(int i = 0; i < required; i++)
{
System.out.print(".");
}
It can be improved on (try strings that are very large for example, or use a StringBuilder rather than System.out.print).

add apache's commons-lang to your classpath and use StringUtils.leftPad()
System.out.println(str1 + StringUtils.leftPad(str2, 40 - str1.length(), '.'));
why write a method to do something someone else has already written + tested?

Related

Splitting a string in an array of strings of limited size

I have a string of a random address like
String s = "H.N.-13/1443 laal street near bharath dental lab near thana qutubsher near modern bakery saharanpur uttar pradesh 247001";
I want to split it into array of string with two conditions:
each element of that array of string is of length less than or equal to 20
No awkward ending of an element of array of string
For example, splitting every 20 characters would produce:
"H.N.-13/1443 laal st"
"reet near bharath de"
"ntal lab near thana"
"qutubsher near moder"
"n bakery saharanpur"
but the correct output would be:
"H.N.-13/1443 laal"
"street near bharath"
"dental lab near"
"thana qutubsher near"
"modern bakery"
"saharanpur"
Notice how each element in string array is less than or equal to 20.
The above is my output for this code:
static String[] split(String s,int max){
int total_lines = s.length () / 24;
if (s.length () % 24 != 0) {
total_lines++;
}
String[] ans = new String[total_lines];
int count = 0;
int j = 0;
for (int i = 0; i < total_lines; i++) {
for (j = 0; j < 20; j++) {
if (ans[count] == null) {
ans[count] = "";
}
if (count > 0) {
if ((20 * count) + j < s.length()) {
ans[count] += s.charAt (20 * count + j);
} else {
break;
}
} else {
ans[count] += s.charAt (j);
}
}
String a = "";
a += ans[count].charAt (0);
if (a.equals (" ")) {
ans[i] = ans[i].substring (0, 0) + "" + ans[i].substring (1);
}
System.out.println (ans[i]);
count++;
}
return ans;
}
public static void main (String[]args) {
String add = "H.N.-13/1663 laal street near bharath dental lab near thana qutubsher near modern bakery";
String city = "saharanpur";
String state = "uttar pradesh";
String zip = "247001";
String s = add + " " + city + " " + state + " " + zip;
String[]ans = split (s);
}
Find all occurrences of up to 20 chars starting with a non-space and ending with a word boundary, and collect them to a List:
List<String> parts = Pattern.compile("\\S.{1,19}\\b").matcher(s)
.results()
.map(MatchResult::group)
.collect(Collectors.toList());
See live demo.
The code is not very clear, but at first glance it seems you are building character by character that is why you are getting the output you see. Instead you go word by word if you want to retain a word and overflow it to next String if necessary. A more promising code would be:
static String[] splitString(String s, int max) {
String[] words = s.split("\s+");
List<String> out = new ArrayList<>();
int numWords = words.length;
int i = 0;
while (i <numWords) {
int len = 0;
StringBuilder sb = new StringBuilder();
while (i < numWords && len < max) {
int wordLength = words[i].length();
len += (i == numWords-1 ? wordLength : wordLength + 1);//1 for space
if (len <= max) {
sb.append(words[i]+ " ");
i++;
}
}
out.add(sb.toString().trim());
}
return out.toArray(new String[] {});
}
Note: It works on your example input, but you may need to tweak it so it works for cases like a long word containing more than 20 characters, etc.

Cut String by maxLines parameter, and by number of characters

I'm writing a class with a method that takes a summary string and breaks it down into a maximum number of lines (maxLines Parameter) and maximum number of characters per line (width parameter). All lines except the first line should be indented (they should start with a space character), but the second character in an indented line should not be another space (so that second space must not be included). The program should still work if you change the maxLine parameter r width.
Also, the code should check whether some special characters are in the String, like:
\' , \" , \\ , \t , \b , \r , \f , \n
How can I inspect is many spaces in String like below? If there are many spaces in the String, I want to trim them, but I don't know how to. (These underscores represent spaces.)
"9:00 John_____________________________Doe until 10 30 at Office"
9:00 Jo
_hn____
_______
_____Do
With my code, I get this result:
9:00 Jo
_hn Doe
_until 1
_0 30 at
But I want THIS this output:
9:00 Jo
_hn Doe
_until_
_10 30_
Here is my code:
public static void main(String[] args) {
String str = "9:00 John Doe until 10 30 at Office";
int width = 7;
int maxLine = 4;
List<String> lisT = new LinkedList<>(getParts(str, width, maxLine));
for (String part : lisT) {
System.out.println(part);
}
}
public static List<String> getParts(String str, int width, int maxLine) {
List<String> parts = new LinkedList<>();
int count = 0;
int len = str.length();
String indent = "";
for (int i = 0; i < len; i += width) {
parts.add(indent + str.substring(i, Math.min(len, i + width)).trim());
count++;
indent = " ";
if (count == maxLine)
break;
}
return parts;
}
So this is what you want? I really hope you don't have to implement this in something because I had to mangle this to make it work. Hopefully this is homework
public static void main(String[] args) {
String str = "9:00 John Doe until 10 30 at Office";
int width = 7;
int maxLine = 4;
List<String> lisT = new LinkedList<>(getParts(str, width, maxLine));
for (String part : lisT) {
System.out.println(part);
}
}
public static List<String> getParts(String str, int width, int maxLine){
List<String> parts = new LinkedList<>();
int endedAt = 0;
boolean firstLine = true;
boolean secondLine = true;
String indent = " ";
for (int i = 0; i < maxLine; i++) {
if(endedAt<=str.length()) {
String holder;
if(firstLine) {
holder = str.substring(endedAt, endedAt + width);
firstLine = false;
}
else {
if(secondLine){
width = width -1;
secondLine = false;
}
holder = indent + str.substring(endedAt, endedAt + width).trim();
}
parts.add(holder);
endedAt = endedAt + width;
}
}
return parts;
}
The output is
9:00 Jo
hn Doe
until
10 30
I think your rows might be too long because your width = 7 includes the indent space, so your rows have a width of 8 instead of 7. I would try replacing for (int i = 0; i < len; i += width) {... with for (int i = 1; i < len; i += width - 1) {... and add a special statement right before the for loop for the 0th row, since you do not want to indent the 0th row. Something like this:
parts.add(str.substring(0, Math.min(len, i + width)).trim());
for(...){...}
Let me know whether that seems to be the problem. If not, I can take another look. To answer your other questions:
To remove more than one space in the middle of a string, use this to replace all whitespace with exactly one space:
String result = replaceAll("\\s","");
You can remove the special characters with a regex like this:
String result = str.replaceAll("[\'\"\\\t\b\r\f\n]","");

How to retain matched sub string and replace unmatched sub strings in Java String

Hello I try to print in an array of Strings
In the following way:
Input: big = "12xy34", small = "xy" output: "** xy **"
Input: big = "" 12xt34 "", small = "xy" output: "******"
Input: big = "12xy34", small = "1" output: "1 *****"
Input: big = "12xy34xyabcxy", small = "xy" output: "** xy ** xy *** xy"
Input: big = "78abcd78cd", small = "78" output: "78 **** 78 **"
What I need to write a condition to receive as up?
public static String stars(String big, String small) {
//throw new RuntimeException("not implemented yet ");
char[] arr = big.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (big.contains(small) ) {
arr[i] = '*';
}
}
String a = Arrays.toString(arr);
return big+""+a;
}
Algorithm:
Convert big and small String's to char[] array's bigC and smallC respectively
Iterate over each character of big String
At every index during iteration, identify whether there is a sub-string possible beginning current character
If there is a sub-string possibility, advance the index in big String iteration by length of small String
Otherwise, replace the character by *
Code:
public class StringRetainer {
public static void main(String args[]) {
String big[] = {"12xy34", "12xt34", "12xy34", "12xy34xyabcxy", "78abcd78cd"};
String small[] = {"xy", "xy", "1", "xy", "78"};
for(int i = 0; i < big.length & i < small.length; i++) {
System.out.println("Input: big = \"" + big[i] + "\", small = \"" + small[i] + "\" output : \"" + stars(big[i], small[i]) + "\"");
}
}
public static String stars(String big, String small) {
//String to char[] array conversions
char[] bigC = big.toCharArray();
char[] smallC = small.toCharArray();
//iterate through every character of big String and selectively replace
for(int i = 0; i < bigC.length; i++) {
//flag to determine whether small String occurs in big String
boolean possibleSubString = true;
int j = 0;
//iterate through every character of small String to determine
//the possibility of character replacement
for(; j < smallC.length && (i+j) < bigC.length; j++) {
//if there is a mismatch of at least one character in big String
if(bigC[i+j] != smallC[j]) {
//set the flag indicating sub string is not possible and break
possibleSubString = false;
break;
}
}
//if small String is part of big String,
//advance the loop index with length of small String
//replace with '*' otherwise
if(possibleSubString)
i = i+j-1;
else
bigC[i] = '*';
}
big = String.copyValueOf(bigC);
return big;
}
}
Note:
This is one possible solution (legacy way of doing)
Looks like there is no straight forward way of making this happen using built-in String/StringBuffer/StringBuilder methods

detect incomplete patterns in strings

i have a string containing nested repeating patterns, for example:
String pattern1 = "1234";
String pattern2 = "5678";
String patternscombined = "1234|1234|5678|9"//added | for reading pleasure
String pattern = (pattern1 + pattern1 + pattern2 + "9")
+(pattern1 + pattern1 + pattern2 + "9")
+(pattern1 + pattern1 + pattern2 + "9")
String result = "1234|1234|5678|9|1234|1234|56";
As you can see in the above example, the result got cut off. But when knowing the repeating patterns, you can predict, what could come next.
Now to my question:
How can i predict the next repetitions of this pattern, to get a resulting string like:
String predictedresult = "1234|1234|5678|9|1234|1234|5678|9|1234|1234|5678|9";
Patterns will be smaller that 10 characters, the predicted result will be smaller than 1000 characters.
I am only receiving the cutoff result string and a pattern recognition program is already implemented and working. In the above example, i would have result, pattern1, pattern2 and patternscombined.
EDIT:
I have found a solution working for me:
import java.util.Arrays;
public class LRS {
// return the longest common prefix of s and t
public static String lcp(String s, String t) {
int n = Math.min(s.length(), t.length());
for (int i = 0; i < n; i++) {
if (s.charAt(i) != t.charAt(i))
return s.substring(0, i);
}
return s.substring(0, n);
}
// return the longest repeated string in s
public static String lrs(String s) {
// form the N suffixes
int N = s.length();
String[] suffixes = new String[N];
for (int i = 0; i < N; i++) {
suffixes[i] = s.substring(i, N);
}
// sort them
Arrays.sort(suffixes);
// find longest repeated substring by comparing adjacent sorted suffixes
String lrs = "";
for (int i = 0; i < N - 1; i++) {
String x = lcp(suffixes[i], suffixes[i + 1]);
if (x.length() > lrs.length())
lrs = x;
}
return lrs;
}
public static int startingRepeats(final String haystack, final String needle)
{
String s = haystack;
final int len = needle.length();
if(len == 0){
return 0;
}
int count = 0;
while (s.startsWith(needle)) {
count++;
s = s.substring(len);
}
return count;
}
public static String lrscutoff(String s){
String lrs = s;
int length = s.length();
for (int i = length; i > 0; i--) {
String x = lrs(s.substring(0, i));
if (startingRepeats(s, x) < 10 &&
startingRepeats(s, x) > startingRepeats(s, lrs)){
lrs = x;
}
}
return lrs;
}
// read in text, replacing all consecutive whitespace with a single space
// then compute longest repeated substring
public static void main(String[] args) {
long time = System.nanoTime();
long timemilis = System.currentTimeMillis();
String s = "12341234567891234123456789123412345";
String repeat = s;
while(repeat.length() > 0){
System.out.println("-------------------------");
String repeat2 = lrscutoff(repeat);
System.out.println("'" + repeat + "'");
int count = startingRepeats(repeat, repeat2);
String rest = repeat.substring(count*repeat2.length());
System.out.println("predicted: (rest ='" + rest + "')" );
while(count > 0){
System.out.print("'" + repeat2 + "' + ");
count--;
}
if(repeat.equals(repeat2)){
System.out.println("''");
break;
}
if(rest!="" && repeat2.contains(rest)){
System.out.println("'" + repeat2 + "'");
}else{
System.out.println("'" + rest + "'");
}
repeat = repeat2;
}
System.out.println("Time: (nano+millis):");
System.out.println(System.nanoTime()-time);
System.out.println(System.currentTimeMillis()-timemilis);
}
}
If your predict String is always piped(|) the numbers then you can easily split them using pipe and then keep track of the counts on a HashMap. For example
1234 = 2
1344 = 1
4411 = 5
But if not, then you have to modify the Longest Repeated Substring algorithm. As you need to have all repeated substrings so keep track of all instead of only the Longest one. Also, you have to put a checking for minimum length of substring along with overlapping substring. By searching google you'll find lot of reference of this algorithm.
You seem to need something like an n-gram language model, which is a statistical model that is based on counts of co-occurring events. If you are given some training data, you can derive the probabilities from counts of seen patterns. If not, you can try to specify them manually, but this can get tricky. Once you have such a language model (where the digit patterns correspond to words), you can always predict the next word by picking one with the highest probability given some previous words ("history").

How to split numbers in java?

I am trying to split number but don't know how to do this.
I referred this link.
https://stackoverflow.com/a/12297231/1395259
Suppose I have a number 12345678.
using above link I am splitting by 3 places.So the output becomes 123 456 78.
But I want it as 12 345 678 And I want to take the string that was split in the form 12.345.678 .
Can anybody help me please??
java.text package provides all reasonable options for formatting numbers
DecimalFormat f = new DecimalFormat("#,###");
DecimalFormatSymbols fs = f.getDecimalFormatSymbols();
fs.setGroupingSeparator('.');
f.setDecimalFormatSymbols(fs);
String s = f.format(12345678);
System.out.println(s);
output
12.345.678
using DecimalFormat directly is very flexible, but typically we can use a shorter version
String s = NumberFormat.getNumberInstance(Locale.GERMAN).format(12345678);
which produces the same string
12.345.678
Different countries have different rules for formatting numbers (and dates). Usually we want our programs to be internationalized / localized and use default locale version
NumberFormat.getNumberInstance().format(number);
One lazy way is to reverse the string, apply above method, and then reverse it again.
You can use StringBuffer's Reverse Function, as shown in Reverse each individual word of "Hello World" string with Java
12345678
87654321
876 543 21
12 345 678
I am assuming of course that you want to split by 3s and the group with <3 digits left appears in the start rather than the end as in the method you link.
The not so lazy way would be to use string length to adapt the method you link to start with length%3 characters.
Using the solution from your link i would rephrase that as following (TESTED!):
public String[] splitStringEvery(String s, int interval) {
int arrayLength = (int) Math.ceil(((s.length() / (double)interval)));
String[] result = new String[arrayLength];
int j = s.length();
int lastIndex = result.length;
for (int i = lastIndex - 1; i > 0; i--) {
result[i] = s.substring(j - interval, j);
j -= interval;
} //Add the last bit
result[0] = s.substring(0, j);
return result;
}
Here is a method that splits an int value and returns an String in the specified format:
public static String split( int n ) {
String result = "", s = Integer.toString( n );
while ( s.length() > 3 ) {
result = s.substring( s.length() -3, s.length() ) + ((result.length() > 0)? "." + result : "" );
s = s.substring( 0, s.length() -3 );
}
return s + "." + result;
}
Input:
12345678
Output:
12.345.678
If it's a String, use StringBuilder or StringBuffer. Here's the code:
public class SplitNumber {
public static void main(String[] args){
int number = 12345678;
String numberStrBefore = Integer.toString(number);
StringBuffer numberStrAfter = new StringBuffer();
numberStrAfter.append(numberStrBefore.charAt(0));
numberStrAfter.append(numberStrBefore.charAt(1));
numberStrAfter.append('.');
numberStrAfter.append(numberStrBefore.charAt(2));
numberStrAfter.append(numberStrBefore.charAt(3));
numberStrAfter.append(numberStrBefore.charAt(4));
numberStrAfter.append('.');
numberStrAfter.append(numberStrBefore.charAt(5));
numberStrAfter.append(numberStrBefore.charAt(6));
numberStrAfter.append(numberStrBefore.charAt(7));
System.out.println("Number Before: " + numberStrBefore);
System.out.println("Number After: " + numberStrAfter.toString());
}
}
And here is the same thing with a method:
public class SplitNumber {
public static void main(String[] args){
int number = 12345678;
int[] split = {2,3,3}; //How to split the number
String numberStrAfter = insertDots(number, split);
System.out.println("Number Before: " + number);
System.out.println("Number After: " + numberStrAfter);
}
public static String insertDots(int number, int[] split){
StringBuffer numberStrAfter = new StringBuffer();
String numberStr = Integer.toString(number);
int currentIndex = 0;
for(int i = 0; i < split.length; i++){
for(int j = 0; j < split[i]; j++){
numberStrAfter.append(numberStr.charAt(currentIndex));
currentIndex++;
}
numberStrAfter.append('.');
}
numberStrAfter.deleteCharAt(numberStrAfter.length()-1); //Removing last "."
return numberStrAfter.toString();
}
}
This version, with the method, allows you to split any number into any format that you want, simply change the "split" variable into the format that you want to split the string into. (Ex: Splitting 12345678 into: 1.1234.5.67.8 would mean that "split" must be set to {1,4,1,2,1}).

Categories

Resources