How to print out all substrings of a string? - java

I searched around and couldn't find this problem listed anywhere and
I spent some time trying to make it work with two loops, but couldn't. I would be interested in anything shorter and more elegant. This is an exercise, but not a homework problem and as the title says I'm supposed to keep it simple i.e. no arrays/list/hash etc.
My work so far:
String str = "string";
String subString;
int k = 1;
while (k <= str.length()) {
for (int i = 0; i < str.length(); i++) {
for (int j = i+1; j <= str.length(); j++) {
subString = str.substring(i,j);
if (subString.length()==k) {System.out.println(subString);}
}
}
k++;
}

You only need 2 nested loops, not 3. You don't need k and j at the same time.
String str = "string";
for (int i = 0; i < str.length(); i++) {
for (int j = i + 1; j <= str.length(); j++) {
System.out.println(str.substring(i, j));
}
}
Output:
s
st
str
stri
strin
string
t
tr
tri
trin
tring
r
ri
rin
ring
i
in
ing
n
ng
g

No need of 3 loops and checking substring size everytime:
Demo:
for (int i = 0; i < str.length(); i++) {
for (int k = 1; k+i <= str.length(); k++) {
subString = str.substring(i,k+i);
System.out.println(subString);
}
}

I saw a couple of similar answers, but this one should have the same output as the original 3-loop version:
String str = "string";
String subString;
for (int k = 1; k <= str.length(); k++) {
for (int i = 0; i+k <= str.length(); i++) {
subString = str.substring(i,i+k);
System.out.println(subString);
}
}

Related

How to add Alphabetical numeration? Test provided

Update: I solved it on my own. Will try to share solution later. Thanks.
Need to order a series of characters using an alphabetical list. [See test below, it is quite self-explanatory] I have problems with it because I don't know where to add the loop (I tried different options but could not find the right one).
I'm trying to add an alphabetic list, like the following one. But replacing the numbers for letters.
Name:
| Something
| Something
| Something
TEST:
expected: <1234
a|v·~·
b|╔╗═┃
c|╚·╚╗
d|·M·^>
but was: <1234
abcdefghijklmnopqrstuvwxyz|v·~·
|╔╗═┃
|╚·╚╗
|·M·^>
Code:
public String toString() {
StringBuilder response = new StringBuilder();
for(int i = 1; i <= size; i++) {
response.append("" + i);
}
response.append("\n");
for(char alphabet = 'a'; alphabet <= 'z'; alphabet++){
response.append(alphabet);
}
for(int i = 0; i < size; i++){
response.append("|");
for (int j = 0; j < size; j++){
response.append(board[i][j].getType().getUnicodeRepresentation());
}
response.append("\n");
}
return response.toString();
}
Adding another try:
TEST
expected: <1234
a|v·~·
b|╔╗═┃
c|╚·╚╗
d|·M·^>
but was: <1234
a|v·~·╔╗═┃╚·╚╗·M·^
b|v·~·╔╗═┃╚·╚╗·M·^
c|v·~·╔╗═┃╚·╚╗·M·^
d|v·~·╔╗═┃╚·╚╗·M·^>
Code:
public String toString() {
StringBuilder response = new StringBuilder();
for(int i = 1; i <= size; i++) {
response.append("" + i);
}
response.append("\n");
for(char alphabet = 'a'; alphabet <= 'd'; alphabet++){
response.append(alphabet);
response.append("|");
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
response.append(board[i][j].getType().getUnicodeRepresentation());
}
}
response.append("\n");
}
return response.toString();
}
Not sure I understood what you're trying to do, but you can try:
for(int i =0, char alphabet = 'a'; alphabet <= 'z'; alphabet++, i++){
response.append(alphabet);
response.append("|");
for (int j = 0; j < size; j++){
response.append(board[i][j].getType().getUnicodeRepresentation());
}
response.append("\n");
}
There might be problems with the indexing(specifically i) because you didn't provide any info about board or size or your intention in general. i will probabily be out of bounds, because something doesn't make sense. From your example it looks like size is 4, but your first loop runs all the way from a to z, so for e, which cells from board should you concat to the string?
One approach would be to index the alphabet and then assign each series of characters to the corresponding index.
The new code would be:
public String toString() {
StringBuilder response = new StringBuilder();
for(int i = 1; i <= size; i++) {
response.append("" + i);
}
response.append("\n");
String[] lines = new String[size];
for(int i = 0, char alphabet = 'a'; alphabet <= 'z' && i < size; alphabet++, i++){
lines[i] = alphabet + "";
}
for(int i = 0; i < size; i++){
lines[i] += ("|");
for (int j = 0; j < size; j++){
lines[i] += board[i][j].getType().getUnicodeRepresentation();
}
}
for(int i = 0; i < size; i++) {
response.append(lines[i]);
response.append("\n");
}
return response.toString();
}

How to print ASCII patterns in C# but using Java syntax?

Code below is for pattern a, feel like once I get a I could get the others.
I like the array[int].length syntax in Java and was helpful to get the pattern to print as shown in the picture. But I do not think such a thing exists in C#.
class Main {
public static void main(String[] args)
{
char[][] arr = new char[10][10];
int starCount = 10;
for(int i = 0; i < arr.length; i++)
{
for(int j = 0; j < starCount; j++)
{
arr[i][j] = '*';
}
for(int k = starCount; k < arr[i].length; k++)
{
arr[i][k] = '-';
}
starCount--;
}
for(int a = 0; a < arr.length; a++)
{
for(int b = 0; b < arr[a].length; b++)
{
System.out.print(arr[a][b]);
}
System.out.println();
}
}
}
This code prints the * in a decreasing fashion but I am struggling with how to replace the empty elements of the array with the - character as shown in the image.
class MainClass {
public static void Main (string[] args)
{
char[ , ] arr = new char[10,10];
int starCount = 10;
for(int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < starCount; j++)
{
arr[i , j] = '*';
}
for (int k = 0; ) //IDK WHAT TO DO TO ASSIGN ARR[I , K] = '-';
starCount--;
}
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Console.Write(arr[i , j]);
}
Console.WriteLine();
}
}
}
You can use two nested for loops and one if else statement to print all of these patterns. This is Java code, but I think it can be easily converted to C#:
int n = 5;
for (int i = -n; i <= n; i++) {
for (int j = -n; j <= n; j++) {
// a) if (i + j <= 0)
// b) if (i + j >= 0)
// c) if (i <= j)
// d) if (Math.abs(i) + Math.abs(j) <= n)
if (i + j <= 0)
System.out.print("*");
else
System.out.print("-");
}
System.out.println();
}
Output (combined):
a) b) c) d)
*********** ----------* *********** -----*-----
**********- ---------** -********** ----***----
*********-- --------*** --********* ---*****---
********--- -------**** ---******** --*******--
*******---- ------***** ----******* -*********-
******----- -----****** -----****** ***********
*****------ ----******* ------***** -*********-
****------- ---******** -------**** --*******--
***-------- --********* --------*** ---*****---
**--------- -********** ---------** ----***----
*---------- *********** ----------* -----*-----
See also: Output an ASCII diamond shape using loops
Here's a different approach to the original problem, which might be easier for you to convert.
Build a string of 10 stars and 9 dashes, e.g. hard-coded that would be:
String line = "**********---------";
Now print a 10 rows with substrings of that string:
for (int i = 0; i < 10; i++)
System.out.println(line.substring(i, i + 10));
Output
**********
*********-
********--
*******---
******----
*****-----
****------
***-------
**--------
*---------
If the size is dynamic, based on an int value in variable starCount, then in Java 11+ you can use the repeat() method:
String line = "*".repeat(starCount) + "-".repeat(starCount - 1);
for (int i = 0; i < starCount; i++)
System.out.println(line.substring(i, i + starCount));
That one should be easy to do in C#. See: Best way to repeat a character in C#.
In versions of Java below 11, you can build a char[]:
char[] line = new char[2 * starCount - 1];
Arrays.fill(line, 0, starCount, '*');
Arrays.fill(line, starCount, line.length, '-');
for (int i = 0; i < starCount; i++)
System.out.println(new String(line, i, starCount));
The easiest way would be to look at the C# documentation for the Array class. There you would find that the Array class has a GetLength() method, that returns what the length property of a Java array returns.
Using that method you can change your code to
class MainClass {
public static void Main (string[] args)
{
char[ , ] arr = new char[10,10];
int starCount = 10;
for(int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < starCount; j++)
{
arr[i , j] = '*';
}
for (int k = starCount; k < arr.GetLength(1); k++)
{
arr[i , k] = '*';
}
starCount--;
}
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i , j]);
}
Console.WriteLine();
}
}
}
For some reason when you switched from java to C# you went from using jagged arrays:
//java
char[][] arr = new char[10][10];
To rectangular arrays:
//c#
char[ , ] arr = new char[10,10];
This undoubtedly makes your life more hard work because it means a lot more has to change. C# supports jagged arrays in exactly the same way Java does, and in fact if I hadn't written "//java" above you wouldn't have been able to tell whether it was C# or java because they're the same
I like the array[int].length syntax in Java ... But I do not think such a thing exists in C#.
It absolutely does, and you need to change just one single character to get it: properties in C# are named in Pascal case, so you want Length, not length
In fact, the logic of that entire block of java you have will work just fine in C# - just paste it in and change the following minor changes:
length -> Length
System.out.print -> Console.Write
System.out.println -> Console.WriteLine

How to hide characters using for loops, respectively?

I want to basically hide characters following three constant dots (...), the pattern goes like this:
Inputs a phrase from the user and outputs the phrase followed by three dots (...), then the phrase minus one character followed by three dots (...), then the phrase minus two characters followed by the dots, and so on until only one dot is left.
Note: This has to be done using nested for loops only
Sample input
1
disappear
Expected output:
disappear...
disappea...
disappe...
disapp...
disap...
disa...
dis...
di...
d...
...
..
.
This is my attempt:
Problem: I am unable to make it so the phrase decreases each time (minus 1 each time)
I tried using the charAt(); method, but it wouldn't work, I am sure that you would need a for loop separate for each of the dots or a whole set of dots, in this case.
import java.util.Scanner;
public class Dissappear{
public static void main(String[]args){
Scanner keyboard = new Scanner(System.in);
int option = keyboard.nextInt();
String phrase = keyboard.next();
if (option == 1){
for (int x = 0; x <= phrase.length(); x++){
System.out.print(phrase + "...");
for (int y = 0; y <= phrase.length(); y++){
char n = phrase.charAt(y);
System.out.print(n+"...");
}
}
}
}
}
This is how I got it to work:
public class Disappear {
public static void main(String... args) {
String word = "disappear";
int originalLength = word.length();
for(int i = 0; i < originalLength; i++) {
System.out.println(word.substring(0, originalLength - i) + "...");
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3 - i; j++) {
System.out.print(".");
}
System.out.println();
}
}
}
Without substring:
public class Disappear {
public static void main(String... args) {
String word = "disappear";
int originalLength = word.length();
for(int i = 0; i < originalLength; i++) {
for(int j = 0; j < originalLength - i; j++) {
System.out.print(word.charAt(j));
}
System.out.println("...");
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3 - i; j++) {
System.out.print(".");
}
System.out.println();
}
}
}
You can do it with StringBuilder:
StringBuilder stringBuilder = new StringBuilder(str);
System.out.println(str + "...");
for (int i = 0; i < length; i++) {
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
System.out.println(stringBuilder.toString() + "...");
if (i == length - 1) {
for (int j = 0; j < 2; j++) {
for (int k = j; k < 2; k++) {
System.out.print(".");
}
System.out.println();
}
}
Ok! Nested for loops. But the outer one is only included to meet the requirement. Probably not in the spirit of the assignment though. Just keep decrementing k until it is zero and then latch it there until the StringBuilder length is 0 and the inner loop terminates.
StringBuilder sb = new StringBuilder("disappear...");
for (;;) {
for (int k = sb.length() - 4; sb.length() > 0;) {
System.out.println(sb);
sb.delete(k, k + 1);
k = k > 0 ? --k : 0;
}
break;
}

Nested for loops to iterate between two strings

I'd like to, using for loops, iterate through each string and output each character turn by turn.
String a = "apple";
String b = "class";
for (int i = 0; i < a.length() ; i++) { // - 1 because 0 = 1
System.out.print(a.charAt(i));
for (int j = 0; j < b.length(); j ++) {
System.out.print(b.charAt(j));
}
}
I'm struggling with the inner loop.
At the moment my output is as followed:
AClasspClasspClasslClasseClass
However, I'd like to achieve the following:
acplpalses
Extended Question:
How about outputting one string in reverse while the other is outputted normally?
Current Attempt:
for (int i = a.length() - 1; i >= 0; i--) {
System.out.println(a.charAt(i));
for (int j = 0; j < b.length(); j ++) {
System.out.println(b.charAt(j));
}
}
However, this simply outputs as above, just with "Apple" in reverse order in the same format as previous:
eclasslclasspclasspclassaclass
You don't need 2 loops as you take the same indice for both Strings
Same Order :
Simple same-size case :
for (int i = 0; i < a.length(); i++) {
System.out.print(a.charAt(i));
System.out.print(b.charAt(i));
}
Complex different-size case :
int minLength = Math.min(a.length(), b.length());
for (int i = 0; i < minLength; i++) {
System.out.print(a.charAt(i));
System.out.print(b.charAt(i));
}
System.out.print(a.substring(minLength)); // prints the remaining if 'a' is longer
System.out.print(b.substring(minLength)); // prints the remaining if 'b' is longer
Different order :
Simple same-size case :
for (int i = 0; i < a.length(); i++) {
System.out.print(a.charAt(i));
System.out.print(b.charAt(b.length() - i - 1));
}
Complex different-size case :
int minLength = Math.min(a.length(), b.length());
for (int i = 0; i < minLength; i++) {
System.out.print(a.charAt(i));
System.out.print(b.charAt(b.length() - i - 1));
}
System.out.print(a.substring(minLength));
System.out.print(new StringBuilder(b).reverse().substring(minLength));
Another solution using Java 8 streams:
System.out.println(
IntStream.range(0, Math.min(a.length(), b.length()))
.mapToObj(i -> "" + a.charAt(i) + b.charAt(i))
.collect(Collectors.joining(""))
);
For the extended question-
Assuming both strings are of same size
for (int i = 0; i < a.length(); i++) {
System.out.print(a.charAt(a.length()-1-i));
System.out.print(b.charAt(i));
}

Can someone help me with the solution to Project Euler #4 in Java?

Okay guys, I know that this is not the most elegant solution for Project Euler's 4th problem, but I'm proud of it because I did it by myself... until now.
Here is the problem for reference:
http://projecteuler.net/index.php?section=problems&id=4
public class Problem4 {
public void projectEuler4() {
int answer = 0;
for (int i = 1; i < 1000; i++) {
for (int j = 1; j < 1000; j++) {
if (i * j >= answer) {
String stringNum = "" + answer;
String firstHalf = "";
String secondHalf = "";
if (stringNum.length() % 2 == 0) {
for (int k = 0; k < stringNum.length() / 2; k++) {
firstHalf = firstHalf + ("" + stringNum.charAt(k));
}
for (int k = stringNum.length(); k < stringNum.length() / 2; k--) {
secondHalf = secondHalf + ("" + stringNum.charAt(k));
}
if (Integer.parseInt(firstHalf) == Integer.parseInt(secondHalf)) {
answer = i * j;
System.out.println(answer);
}
}
}
}
}
}
}
This code for(int k = stringNum.length(); k < stringNum.length()/2; k--)
You have the comparison messed up (< instead of >) and also you start from stringNum.length(), while the last character is at position stringNum.length() - 1.
However there are a lot of things you can improve codewise:
No need to do "abc"+(""+'d'), you can directly do "abc"+'d'
No need to Integer.parseInt("123") == Integer.parseInt("123"), you can directly do "123".equals("123")
Your second loop
for(int k = stringNum.length(); k < stringNum.length()/2; k--)
you are counting down so your terminating condition is wrong

Categories