markdown algorithm java; converter problems - java

public class Md2html {
public static void main(String[] args) throws IOException {
String stringToConvert = new Scanner(System.in).nextLine();
System.out.println(convert(stringToConvert));
}
public static String convert(String str) {
if (str.equals("# "))
System.out.println(" ");
Pattern pattern = Pattern.compile("(#+[^#]+)");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String str1 = matcher.group(1);
if(str1.replaceFirst("#+", "").length() == 0 ||
str1.replaceFirst("#+", "").matches("[\\s]+"))
continue;
int n = str1.length() - str1.replaceFirst("#+", "").length();
System.out.println("<h" + n + ">" + str1.substring(n) +
"</h" + n + ">");
double carac;
carac = str.charAt(0);
if(carac>65 & carac <=90) {
System.out.print("<p>");
System.out.println(str);
System.out.println("<p>");
}
}
return ("");
}
}
Ok, so now I have an algorithm that converts # to < h1> < h2> depending on the number of #...I'm now trying to add < p> at the beginning of a paragraph and < /p> at the end of it. For some reason,the second part of the converter, which is supposed to add < p> at the beginning and < /p> at the end of a paragraph doesnt seem to work (it's the code starting with double carac). Can someone tell me what I'm doing wrong???

You are printing two opening tags for a paragraph if the string starts with an uppercase letter and no closing tag. Replace
System.out.print("<p>");
System.out.println(str);
System.out.println("<p>");
with
System.out.print("<p>");
System.out.println(str);
System.out.println("</p>"); //<--here
Also, you should use a logical AND && instead of a bitwise AND & for boolean operations.
Also, String#charAt(int) returns a char, not a double. You are declaring carac as a double. Declare as a char instead.

Related

Is there a way to find out how many numbers are at the end of a string without knowing the exact index?

I have a method that extracts a certain substring from a string. This substring consists of the numbers in the string. Then this is parsed to an integer.
Method:
protected int startIndex() throws Exception {
String str = getWorkBook().getDefinedName("XYZ");
String sStr = str.substring(10,13);
return Integer.parseInt(sStr) - 1;
}
Example:
String :
'0 DB'!$B$460
subString :
460
Well, I manually entered the index range for the substring. But I would like to automate it.
My approach:
String str = getWorkBook().getDefinedName("XYZ");
int length = str.length();
String sStr = str.substring(length - 3, length);
This works well for this example.
Now there is the problem that the numbers at the end of the string can also be 4 or 5 digits. If that is the case, I naturally get a NullPointerException.
Is there a way or another approach to find out how many numbers are at the end of the string?
You can use the regex, (?<=\D)\d+$ which means one or more digits (i.e. \d+) from the end of the string, preceded by non-digits (i.e. \D).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getNumber("'0 DB'!$B$460"));
}
static String getNumber(String str) {
Matcher matcher = Pattern.compile("(?<=\\D)\\d+$").matcher(str);
if (matcher.find()) {
return matcher.group();
}
// If no match is found, return the string itself
return str;
}
}
In your case I would recommend to use regex with replaceAll like this:
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
This will extract the all the digits in the end or your String or any length.
Also I think you are missing the case when there are no digit in your String, for that I would recommend to check your string before you convert it to an Integer.
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
if (!sStr.isEmpty()) {
return Integer.parseInt(sStr) - 1;
}
return 0; // or any default value
If you just want to get the last number, you can go through the entire string on revert and get the start index:
protected static int startIndex() {
String str = getWorkBook().getDefinedName("XYZ");
if(Character.isDigit(str.charAt(str.length() - 1))) {
for(int i = str.length() - 1; i >= 0; i--){
if(!Character.isDigit(str.charAt(i)))
return i+1;
}
}
return -1;
}
and then print it:
public static void main(String[] args) {
int start = startIndex();
if(start != -1)
System.out.println(getWorkBook().getDefinedName("XYZ").substring(start));
else
System.out.println("No Number found");
}
You will have to add the
Simple and fast solution without RegEx:
public class Main
{
public static int getLastNumber(String str) {
int index = str.length() - 1;
while (index > 0 && Character.isDigit(str.charAt(index)))
index--;
return Integer.parseInt(str.substring(index + 1));
}
public static void main(String[] args) {
final String text = "'0 DB'!$B$460";
System.out.println(getLastNumber(text));
}
}
The output will be:
460
If I were going to do this I just search from the end. This is quite efficient. It returns -1 if no positive number is found. Other return options and the use of an OptionalInt could also be used.
String s = "'0 DB'!$B$460";
int i;
for (i = s.length(); i > 0 && Character.isDigit(s.charAt(i-1)); i--);
int vv = (i < s.length()) ? Integer.valueOf(s.substring(i)) : -1;
System.out.println(vv);
Prints
460
If you know that there will always be a number at the end you can forget the ternary (?:) above and just do the following:
int vv = Integer.valueOf(s.substring(i));

Read string format and fetch required irregular data

I have a string format like this which is output of
readAllBytes(new String(Files.readAllBytes(Paths.get(data))
from a file
a+2 b+3 c+33 d+88 ......
My scenario is I want to get the data after c+" ". The position of c is not constant but c occurs only once. It may occur anywhere. My required value will always be after c+ only. The required size of value 33.....is also not constant. Can someone help me with the optimal code please? I think collections need to be used here.
You can use this regex which will let you capture the data you want,
c\+(\d+)
Explanation:
c+ matches a literal c character immediately followed by a + char
(\d+) captures the next digit(s) which you are interested in capturing.
Demo, https://regex101.com/r/jfYUPG/1
Here is a java code for demonstrating same,
public static void main(String args[]) {
String s = "a+2 b+3 c+33 d+88 ";
Pattern p = Pattern.compile("c\\+(\\d+)");
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println("Data: " + m.group(1));
} else {
System.out.println("Input data doesn't match the regex");
}
}
This gives following output,
Data: 33
This code is extracting the value right after c+ up to the next space, or to the end of the string if there is no space:
String str = "a+2 b+3 c+33 d+88 ";
String find = "c+";
int index = str.indexOf(" ", str.indexOf(find) + 2);
if (index == -1)
index = str.length();
String result = str.substring(str.indexOf(find) + 2, index);
System.out.println(result);
prints
33
or in a method:
public static String getValue(String str, String find) {
int index = str.indexOf(find) + 2;
int indexSpace = str.indexOf(" ", index);
if (indexSpace == -1)
indexSpace = str.length();
return str.substring(index, indexSpace);
}
public static void main(String[] args) {
String str = "a+2 b+3 c+33 d+88 ";
String find = "c+";
System.out.println(getValue(str, find));
}

How to find first character after second dot java

Do you have any ideas how could I get first character after second dot of the string.
String str1 = "test.1231.asdasd.cccc.2.a.2";
String str2 = "aaa.1.22224.sadsada";
In first case I should get a and in second 2.
I thought about dividing string with dot, and extracting first character of third element. But it seems to complicated and I think there is better way.
How about a regex for this?
Pattern p = Pattern.compile(".+?\\..+?\\.(\\w)");
Matcher m = p.matcher(str1);
if (m.find()) {
System.out.println(m.group(1));
}
The regex says: find anything one or more times in a non-greedy fashion (.+?), that must be followed by a dot (\\.), than again anything one or more times in a non-greedy fashion (.+?) followed by a dot (\\.). After this was matched take the first word character in the first group ((\\w)).
Usually regex will do an excellent work here. Still if you are looking for something more customizable then consider the following implementation:
private static int positionOf(String source, String target, int match) {
if (match < 1) {
return -1;
}
int result = -1;
do {
result = source.indexOf(target, result + target.length());
} while (--match > 0 && result > 0);
return result;
}
and then the test is done with:
String str1 = "test..1231.asdasd.cccc..2.a.2.";
System.out.println(positionOf(str1, ".", 3)); -> // prints 10
System.out.println(positionOf(str1, "c", 4)); -> // prints 21
System.out.println(positionOf(str1, "c", 5)); -> // prints -1
System.out.println(positionOf(str1, "..", 2)); -> // prints 22 -> just have in mind that the first symbol after the match is at position 22 + target.length() and also there might be none element with such index in the char array.
Without using pattern, you can use subString and charAt method of String class to achieve this
// You can return String instead of char
public static char returnSecondChar(String strParam) {
String tmpSubString = "";
// First check if . exists in the string.
if (strParam.indexOf('.') != -1) {
// If yes, then extract substring starting from .+1
tmpSubString = strParam.substring(strParam.indexOf('.') + 1);
System.out.println(tmpSubString);
// Check if second '.' exists
if (tmpSubString.indexOf('.') != -1) {
// If it exists, get the char at index of . + 1
return tmpSubString.charAt(tmpSubString.indexOf('.') + 1);
}
}
// If 2 '.' don't exists in the string, return '-'. Here you can return any thing
return '-';
}
You could do it by splitting the String like this:
public static void main(String[] args) {
String str1 = "test.1231.asdasd.cccc.2.a.2";
String str2 = "aaa.1.22224.sadsada";
System.out.println(getCharAfterSecondDot(str1));
System.out.println(getCharAfterSecondDot(str2));
}
public static char getCharAfterSecondDot(String s) {
String[] split = s.split("\\.");
// TODO check if there are values in the array!
return split[2].charAt(0);
}
I don't think it is too complicated, but using a directly matching regex is a very good (maybe better) solution anyway.
Please note that there might be the case of a String input with less than two dots, which would have to be handled (see TODO comment in the code).
You can use Java Stream API since Java 8:
String string = "test.1231.asdasd.cccc.2.a.2";
Arrays.stream(string.split("\\.")) // Split by dot
.skip(2).limit(1) // Skip 2 initial parts and limit to one
.map(i -> i.substring(0, 1)) // Map to the first character
.findFirst().ifPresent(System.out::println); // Get first and print if exists
However, I recommend you to stick with Regex, which is safer and a correct way to do so:
Here is the Regex you need (demo available at Regex101):
.*?\..*?\.(.).*
Don't forget to escape the special characters with double-slash \\.
String[] array = new String[3];
array[0] = "test.1231.asdasd.cccc.2.a.2";
array[1] = "aaa.1.22224.sadsada";
array[2] = "test";
Pattern p = Pattern.compile(".*?\\..*?\\.(.).*");
for (int i=0; i<array.length; i++) {
Matcher m = p.matcher(array[i]);
if (m.find()) {
System.out.println(m.group(1));
}
}
This code prints two results on each line: a, 2 and an empty lane because on the 3rd String, there is no match.
A plain solution using String.indexOf:
public static Character getCharAfterSecondDot(String s) {
int indexOfFirstDot = s.indexOf('.');
if (!isValidIndex(indexOfFirstDot, s)) {
return null;
}
int indexOfSecondDot = s.indexOf('.', indexOfFirstDot + 1);
return isValidIndex(indexOfSecondDot, s) ?
s.charAt(indexOfSecondDot + 1) :
null;
}
protected static boolean isValidIndex(int index, String s) {
return index != -1 && index < s.length() - 1;
}
Using indexOf(int ch) and indexOf(int ch, int fromIndex) needs only to examine all characters in worst case.
And a second version implementing the same logic using indexOf with Optional:
public static Character getCharAfterSecondDot(String s) {
return Optional.of(s.indexOf('.'))
.filter(i -> isValidIndex(i, s))
.map(i -> s.indexOf('.', i + 1))
.filter(i -> isValidIndex(i, s))
.map(i -> s.charAt(i + 1))
.orElse(null);
}
Just another approach, not a one-liner code but simple.
public class Test{
public static void main (String[] args){
for(String str:new String[]{"test.1231.asdasd.cccc.2.a.2","aaa.1.22224.sadsada"}){
int n = 0;
for(char c : str.toCharArray()){
if(2 == n){
System.out.printf("found char: %c%n",c);
break;
}
if('.' == c){
n ++;
}
}
}
}
}
found char: a
found char: 2

Removing contiguous spaces in a String without trim() and replaceAll()

I have to remove leading and trailing spaces from the given string as well as combine the contiguous spaces. For example,
String str = " this is a string containing numerous whitespaces ";
and I need to return it as:
"this is a string containing numerous whitespaces";
But the problem is I can't use String#trim(). (This is a homework and I'm not allowed to use such methods.) I'm currently trying it by accessing each character one-by-one but quite unsuccessful.
I need an optimized code for this. Could anybody help? I need it to be done by today :(
EDIT: Answer posted before we were told we couldn't use replaceAll. I'm leaving it here on the grounds that it may well be useful to other readers, even if it's not useful to the OP.
I need an optimized code for this.
Do you really need it to be opimtized? Have you identified this as a bottleneck?
This should do it:
str = str.replaceAll("\\s+", " ");
That's a regular expression to say "replace any contintiguous whitespace with a single space". It may not be the fastest possible, but I'd benchmark it before trying anything else.
Note that this will replace all whitespace with spaces - so if you have tabs or other whitespace characters, they will be replaced with spaces too.
I'm not permitted to use these methods. I've to do this with loops
and all.
So i wrote for you some little snipet of code if you can't use faster and more efficient way:
String str = " this is a string containing numerous whitespaces ";
StringBuffer buff = new StringBuffer();
String correctedString = "";
boolean space = false;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == ' ') {
if (!space && i > 0) {
buff.append(c);
}
space = true;
}
else {
buff.append(c);
space = false;
}
}
String temp = buff.toString();
if (temp.charAt(temp.length() - 1) == ' ') {
correctedString = temp.substring(0, buff.toString().length() - 1);
System.out.println(correctedString);
}
System.out.println(buff.toString())
Note:
But this is "harcoded" and only for "learning".
More efficient way is for sure use approaches pointed out by #JonSkeet and #BrunoReis
What about str = str.replaceAll(" +", " ").trim();?
If you don't want to use trim() (and I really don't see a reason not to), replace it with:
str = str.replaceAll(" +", " ").replaceAll("^ ", "").replaceAll(" $", "");`
Remove White Spaces without Using any inbuilt library Function
this is just a simple example with fixed array size.
public class RemWhite{
public static void main(String args[]){
String s1=" world qwer ";
int count=0;
char q[]=new char[9];
char ch[]=s1.toCharArray();
System.out.println(ch);
for(int i=0;i<=ch.length-1;i++)
{
int j=ch[i];
if(j==32)
{
continue;
}
else
q[count]=ch[i];
count++;
}
System.out.println(q);
}}
To remove single or re-occurrence of space.
public class RemoveSpace {
public static void main(String[] args) {
char space = ' ';
int ascii = (int) space;
String str = " this is a string containing numerous whitespaces ";
char c[] = str.toCharArray();
for (int i = 0; i < c.length - 1; i++) {
if (c[i] == ascii) {
continue;
} else {
System.out.print(c[i]);
}
}
}
}
If you don't want to use any inbuilt methods here's what you refer
private static String trim(String s)
{
String s1="";boolean nonspace=false;
for(int i=0;i<s.length();i++)
{
if(s.charAt(i)!=' ' || nonspace)
{
s1 = s1+s.charAt(i);
nonspace = true;
}
}
nonspace = false;
s="";
for(int i=s1.length()-1;i>=0;i--)
{
if(s1.charAt(i)!=' ' || nonspace)
{
s = s1.charAt(i)+s;
nonspace = true;
}
}
return s;
}
package removespace;
import java.util.Scanner;
public class RemoveSpace {
public static void main(String[] args) {
Scanner scan= new Scanner(System.in);
System.out.println("Enter the string");
String str= scan.nextLine();
String str2=" ";
char []arr=str.toCharArray();
int i=0;
while(i<=arr.length-1)
{
if(arr[i]==' ')
{
i++;
}
else
{
str2= str2+arr[i];
i++;
}
}
System.out.println(str2);
}
}
This code is used for removing the white spaces and re-occurrence of alphabets in the given string,without using trim(). We accept a string from user. We separate it in characters by using charAt() then we compare each character with null(' '). If null is found we skip it and display that character in the else part. For skipping the null we increment the index i by 1.
try this code to get the solution of your problem.
String name = " abc ";
System.out.println(name);
for (int i = 0; i < name.length(); i++) {
char ch = name.charAt(i);
if (ch == ' ') {
i = 2 + i - 2;
} else {
System.out.print(name.charAt(i));
}
}

Generate fixed length Strings filled with whitespaces

I need to produce fixed length string to generate a character position based file. The missing characters must be filled with space character.
As an example, the field CITY has a fixed length of 15 characters. For the inputs "Chicago" and "Rio de Janeiro" the outputs are
" Chicago"
" Rio de Janeiro".
Since Java 1.5 we can use the method java.lang.String.format(String, Object...) and use printf like format.
The format string "%1$15s" do the job. Where 1$ indicates the argument index, s indicates that the argument is a String and 15 represents the minimal width of the String.
Putting it all together: "%1$15s".
For a general method we have:
public static String fixedLengthString(String string, int length) {
return String.format("%1$"+length+ "s", string);
}
Maybe someone can suggest another format string to fill the empty spaces with an specific character?
Utilize String.format's padding with spaces and replace them with the desired char.
String toPad = "Apple";
String padded = String.format("%8s", toPad).replace(' ', '0');
System.out.println(padded);
Prints 000Apple.
Update more performant version (since it does not rely on String.format), that has no problem with spaces (thx to Rafael Borja for the hint).
int width = 10;
char fill = '0';
String toPad = "New York";
String padded = new String(new char[width - toPad.length()]).replace('\0', fill) + toPad;
System.out.println(padded);
Prints 00New York.
But a check needs to be added to prevent the attempt of creating a char array with negative length.
This code will have exactly the given amount of characters; filled with spaces or truncated on the right side:
private String leftpad(String text, int length) {
return String.format("%" + length + "." + length + "s", text);
}
private String rightpad(String text, int length) {
return String.format("%-" + length + "." + length + "s", text);
}
For right pad you need String.format("%0$-15s", str)
i.e. - sign will "right" pad and no - sign will "left" pad
See my example:
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("================================");
for(int i=0;i<3;i++)
{
String s1=sc.nextLine();
Scanner line = new Scanner( s1);
line=line.useDelimiter(" ");
String language = line.next();
int mark = line.nextInt();;
System.out.printf("%s%03d\n",String.format("%0$-15s", language),mark);
}
System.out.println("================================");
}
}
The input must be a string and a number
example input : Google 1
String.format("%15s",s) // pads left
String.format("%-15s",s) // pads right
Great summary here
import org.apache.commons.lang3.StringUtils;
String stringToPad = "10";
int maxPadLength = 10;
String paddingCharacter = " ";
StringUtils.leftPad(stringToPad, maxPadLength, paddingCharacter)
Way better than Guava imo. Never seen a single enterprise Java project that uses Guava but Apache String Utils is incredibly common.
You can also write a simple method like below
public static String padString(String str, int leng) {
for (int i = str.length(); i <= leng; i++)
str += " ";
return str;
}
The Guava Library has Strings.padStart that does exactly what you want, along with many other useful utilities.
Here's a neat trick:
// E.g pad("sss","00000000"); should deliver "00000sss".
public static String pad(String string, String pad) {
/*
* Add the pad to the left of string then take as many characters from the right
* that is the same length as the pad.
* This would normally mean starting my substring at
* pad.length() + string.length() - pad.length() but obviously the pad.length()'s
* cancel.
*
* 00000000sss
* ^ ----- Cut before this character - pos = 8 + 3 - 8 = 3
*/
return (pad + string).substring(string.length());
}
public static void main(String[] args) throws InterruptedException {
try {
System.out.println("Pad 'Hello' with ' ' produces: '"+pad("Hello"," ")+"'");
// Prints: Pad 'Hello' with ' ' produces: ' Hello'
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the code with tests cases ;) :
#Test
public void testNullStringShouldReturnStringWithSpaces() throws Exception {
String fixedString = writeAtFixedLength(null, 5);
assertEquals(fixedString, " ");
}
#Test
public void testEmptyStringReturnStringWithSpaces() throws Exception {
String fixedString = writeAtFixedLength("", 5);
assertEquals(fixedString, " ");
}
#Test
public void testShortString_ReturnSameStringPlusSpaces() throws Exception {
String fixedString = writeAtFixedLength("aa", 5);
assertEquals(fixedString, "aa ");
}
#Test
public void testLongStringShouldBeCut() throws Exception {
String fixedString = writeAtFixedLength("aaaaaaaaaa", 5);
assertEquals(fixedString, "aaaaa");
}
private String writeAtFixedLength(String pString, int lenght) {
if (pString != null && !pString.isEmpty()){
return getStringAtFixedLength(pString, lenght);
}else{
return completeWithWhiteSpaces("", lenght);
}
}
private String getStringAtFixedLength(String pString, int lenght) {
if(lenght < pString.length()){
return pString.substring(0, lenght);
}else{
return completeWithWhiteSpaces(pString, lenght - pString.length());
}
}
private String completeWithWhiteSpaces(String pString, int lenght) {
for (int i=0; i<lenght; i++)
pString += " ";
return pString;
}
I like TDD ;)
Apache common lang3 dependency's StringUtils exists to solve Left/Right Padding
Apache.common.lang3 provides the StringUtils class where you can use the following method to left padding with your preferred character.
StringUtils.leftPad(final String str, final int size, final char padChar);
Here, This is a static method and the parameters
str - string needs to be pad (can be null)
size - the size to pad to
padChar the character to pad with
We have additional methods in that StringUtils class as well.
rightPad
repeat
different join methods
I just add the Gradle dependency here for your reference.
implementation 'org.apache.commons:commons-lang3:3.12.0'
https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.12.0
Please see all the utils methods of this class.
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
GUAVA Library Dependency
This is from jricher answer. The Guava Library has Strings.padStart that does exactly what you want, along with many other useful utilities.
This code works great.
String ItemNameSpacing = new String(new char[10 - masterPojos.get(i).getName().length()]).replace('\0', ' ');
printData += masterPojos.get(i).getName()+ "" + ItemNameSpacing + ": " + masterPojos.get(i).getItemQty() +" "+ masterPojos.get(i).getItemMeasure() + "\n";
Happy Coding!!
public static String padString(String word, int length) {
String newWord = word;
for(int count = word.length(); count < length; count++) {
newWord = " " + newWord;
}
return newWord;
}
This simple function works for me:
public static String leftPad(String string, int length, String pad) {
return pad.repeat(length - string.length()) + string;
}
Invocation:
String s = leftPad(myString, 10, "0");
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
int s;
String s1 = sc.next();
int x = sc.nextInt();
System.out.printf("%-15s%03d\n", s1, x);
// %-15s -->pads right,%15s-->pads left
}
}
}
Use printf() to simply format output without using any library.

Categories