У меня есть только 6 месяцев опыта Java (и я тоже новичок здесь), поэтому, пожалуйста, несите меня, если в моем коде не все выглядит правильно. Обратите внимание, что это все еще продолжается. Я пытаюсь написать программу, которая принимает строки и печатает только те, которые являются палиндромами.
Я должен: - создать метод с именем isPalindrome, который имеет параметр String и - возвращает логическое значение, основанное на том, является ли строка палиндром или нет. Затем - измените основной метод использования isPalindrome для печати только палиндромов.
Например, если я набираю: "madma James apple mom timer", он должен печатать "мадам" и "мама".
Это в основном программа, которую я пытаюсь написать: Ex: Позвольте использовать слово "мадам". Программа проверяет соответствие первой и последней букв (" m ada m "). Если это так, то он проверяет следующие буквы, на этот раз "a" и "a" ("m a d a m") и так далее и т.д.
Это код Java, который у меня есть до сих пор:
public class Palindrome
{
private String theWord; //Error: The value of the field Palindrome.theWord is not used
public boolean isPalindrome( String theWord ) {
int firstPointer = 0;
int secondPointer = theWord.length() - 1;
for ( int i = 0; i < theWord.length( ); i++ ) {
if ( theWord.charAt[0] == theWord.charAt (theWord.length() - 1) ) { //Error: charAt cannot be resolved or is not a field
return true;
}
return false;
}
}
public static void main( String[] theWord ) {
Palindrome = new Palindrome( ); //Error: Palindrome cannot be resolved to a variable
for ( int i = 0; i < theWord.length; i++ ) {
while (firstPointer < secondPointer) { //Error: "firstPointer" cannot be resolved to a variable. "secondPointer" cannot be resolved to a variable
if ( theWord.charAt[0] == theWord.charAt (theWord.length() - 1) ) { //Error: charAt cannot be resolved to a variable or is not a field. Cannot invoke length() on the array type String[]
firstPointer++; //Error: "firstPointer" cannot be resolved to a variable
secondPointer++; //Error: "secondPointer" cannot be resolved to a variable
}
System.out.println(theWord);
}
}
}
}
Любая помощь, зная, где я пошла не так, была бы весьма признательна. Пожалуйста, не просто дайте мне правильный код. Я хотел бы это выяснить. Большое спасибо.
** EDIT: теперь я включил ошибки в комментарии в коде. Кстати, я использую Eclipse.
→ ** EDIT 2: Хорошо, ребята. Я прочитал большинство ваших ответов и смог исправить большую часть своего кода до сих пор (Спасибо вам все так много). Единственная часть, с которой я все еще сталкиваюсь сейчас, - это эта часть:
if ( theWord.charAt(i) == theWord.charAt (theWord.length() - i - 1) ) {
leftPointer++;
rightPointer--;
Теперь я получаю сообщение "Не могу вызвать charAt (int) для типа массива String []" и "Невозможно вызвать length() для типа массива String []". Это две оставшиеся ошибки, затем я проверю код. Я пытался решить их какое-то время, но я все еще не совсем уверен, что означают эти ошибки.
Eclipse предполагает, что я изменяю theWord.charAt(i) на theWord.length, который не то, что я хочу. Также предлагается удалить "()" по длине, но я тоже не думаю, что это так.
Глядя на ваш метод isPalindrome
:
if ( theWord.charAt(0) == theWord.charAt (theWord.length() - 1)
здесь вы всегда сравниваете первый символ с последним символом. На каждой итерации вы должны сравнивать разные пары символов, пока не найдете пару, которая не соответствует или достигнет середины слова.
Вы должны использовать переменную i
вашего цикла:
if ( theWord.charAt(i) == theWord.charAt (theWord.length() - i - 1)
И возвращаемое значение должно быть абсолютно противоположным. Если вы найдете пару символов, которые не совпадают, вы возвращаете false
. Только если цикл завершается без возврата false
, вы возвращаете true
.
until you find a pair that doesn't match, **or reach the middle of the word**
.
Ладно, пусть все сломается на маленькие значительные куски.
Распечатайте слова в строке, которые были палиндромами.
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a sentence: ");
String sentence = scan.nextLine(); // 1.
String[] words = sentence.split(" ");
for (String word : words) { // 3.
if (isPalindrome(word)) {
System.out.println(word);
}
}
}
/**
* Check if the string is a palindrome.
* @param string
* @return True if string is palindrome.
*/
public static boolean isPalindrome(String string) { // 2.
for (int i = 0; i < string.length() / 2; i++) {
if (string.charAt(i) != string.charAt(string.length() - i - 1)) {
return false;
}
}
return true;
}}
Метод/функция isPalindrome является статическим, потому что мы вызываем его из статического контекста, который является основной функцией. Если вы хотите использовать его нестатически, вы поместите его в класс и создадите объект из этого класса. Остальное должно быть понятно. :-)
Самый короткий путь, вероятно, просто следует за определением: если вы отмените строку, и она останется прежней, то это палиндром:
public static boolean isPalindrome(String input)
{
String reverse = new StringBuilder(input).reverse().toString();
return input.equalsIgnoreCase(reverse);
}
Но если есть образовательная цель (?), И по каким-то причинам следует использовать итераторы, то imho имеет смысл перебирать извне внутрь строки.
public static boolean isPalindrome(String input)
{
int length = input.length();
for (int i = 0; i < length/2 ; i++)
{
if (input.charAt(i) != (input.charAt(length-1-i))) return false;
}
return true;
}
В вашем примере вы использовали вход основного параметра String[]
. Вот лишь некоторая информация, если вы хотите разбить ее на слова вручную.
Эквивалент того, что вы получили сейчас:
String[] words = phrase.split("\\s+");
for (String word : words)
{
// do stuff
}
Метод split
использует разделитель для разбиения String
на String[]
. Разделитель \\s
является регулярным выражением, которое представляет все виды пробелов (не только пробелы, но также вкладки, символы новой строки и т.д.).
Но это не идеально (и ни один из них не является вашим путем), в этой фразе все еще могут быть запятые, точки и другие знаки. Вы можете отфильтровать эти символы на итерации, используя метод Character.isLetterOrDigit
. Кроме того, вы можете просто выполнить replace(...)
чтобы удалить запятую, точки и другие метки. Или вы могли бы использовать более сложные регулярные выражения.
Первое сообщение об ошибке: "Значение поля не используется". Сообщение об ошибке вызвано глобальным частным полем theWord
, поскольку оно никогда не используется. Он не используется, потому что у вас также есть параметр с тем же именем внутри метода isPalindrom(String theWord)
. Всякий раз, когда вы ссылаетесь на theWord
внутри этого метода, он всегда дает преимущество аргументам метода перед рассмотрением глобальных переменных.
Похоже, вы застряли здесь с дизайнерским противоречием. Что такое класс Palindrome
? Есть 2 варианта:
Math
? boolean value = Palindrome.isPalindrome("madam");
?boolean value = new Palindrome("madam").isPalindrome();
Вариант 1: панель инструментов:
public class Palindrome
{
// removed the private field theWord
// make this method static !!
public static boolean isPalindrome( String theWord ) {
...
}
public static void main( String[] theWord ) {
// remove the Palindrome object
// inside the loop check use the static method
// which does not require an object.
if ( Palindrome.isPalindrome(word))
{
}
}
}
Вариант 2: объект
public class Palindrome
{
// keep the private field theWord
private String theWord;
public Palindrome(String theWord)
{
// set the value of the argument to the private field
this.theWord = theWord;
}
// don't make this method static
// also you don't need the parameter any more.
// it will now use the global field theWord instead of a parameter.
public boolean isPalindrome() {
...
}
public static void main( String[] theWord ) {
// inside the loop check use an object
Palindrome palindrome = new Palindrome(word);
if ( palindrome.isPalindrome())
{
}
}
Что касается ошибок в отношении firstPointer и secondPointer. Вам необходимо определить и инициализировать эти переменные. Т.е. поместите int firstPointer = 0;
перед циклом.
В цикле проверьте это так:
boolean isPalin = true;
for ( int i = 0; i < theWord.length( )/2; i++ ) { // loop goes till half since no need to check after that
if ( !(theWord.charAt(i) == theWord.charAt (theWord.length() - 1 - i)) ) { // will check each letter with each end letter
isPalin = false;
break;
}
}
return isPalin;
Еще одна вещь, которую нужно добавить -
1 - firstPointer secondPointer - это локальные переменные to isPalindrome
2 - Когда u декалирует theWord как глобальную переменную, то, кажется, необходимо передать ее. Вы можете использовать его в одном классе.
3 - theWord в main (String [] theWord) потребует от вас ввода ввода в качестве аргументов, лучше использовать консольный ввод во время выполнения.
4 - В основном вы должны разделить каждое слово и передать его isPalindrome. В вашем коде вы не вызываете isPalindrome для проверки в любом месте.
while (firstPointer < secondPointer)
...firstPointer
иsecondPointer
являются локальными переменными в другой функцииisPalindrome
... вы не можете использовать их здесь.