Професионална програма
Loading...
MartinBG avatar MartinBG 3862 Точки

Регекса, който използваш не хваща всички случаи.

Ето примерен вариант, който покрива условието (питай, ако нещо не ти е ясно по него):

^@#+(?=[A-Z])([A-Za-z0-9]{6,})(?<=[A-Z])@#+$

 

Това e решението ти с оправен регекс и разкоментиран код за принтиране на default product group (взема 100/100 в Judge)

 

Ето едно решение и от мен:

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import java.util.stream.IntStream;

public class FancyBarcodes {

    public static void main(String[] args) {
        String regex = "^@#+(?=[A-Z])(?<barcode>[A-Za-z0-9]{6,})(?<=[A-Z])@#+$";
        Pattern pattern = Pattern.compile(regex);
        Scanner scanner = new Scanner(System.in);

        int barcodesCount = Integer.parseInt(scanner.nextLine());

        IntStream.range(0, barcodesCount)
                .mapToObj(i -> {
                    Matcher matcher = pattern.matcher(scanner.nextLine());

                    if (!matcher.matches()) {
                        return "Invalid barcode";
                    }

                    String barcode = matcher.group("barcode");
                    String productGroup = barcode.codePoints()
                            .filter(Character::isDigit)
                            .mapToObj(c -> (char) c)
                            .collect(Collector.of(
                                    StringBuilder::new,
                                    StringBuilder::append,
                                    StringBuilder::append,
                                    sb -> sb.length() == 0 ? "00" : sb.toString()));

                    return "Product group: " + productGroup;
                })
                .forEach(System.out::println);
    }
}

 

1
08/04/2020 06:30:57
Sirakov4444 avatar Sirakov4444 11 Точки

Здравейте,снощи с 300 зора стигнах до 80/100  https://pastebin.com/AjUqN35r и сега като смених regexa с Вашия ми даде 100/100,благодаря за помощта.

Относно Вашето решение,струва ми се на малко по-високо ниво,отколкото мога да понеса,но си го запазвам за да го гледам.

^@#+(?=[A-Z])(?<barcode>[A-Za-z0-9]{6,})(?<=[A-Z])@#+$

Понеже оставихте възможност за въпроси ,искам да попитам за това : (?=[A-Z]) и това: (?<=[A-Z]),за сега съм използвал

само : ?<barcode> ,което създава име/етикетче за групата,до колкото си го представям,горните създават "от-до" граница, от главна буква [A-Z] ,за средната група "barcode".

Също така пробвах какви ли не начини и варианти,комбинации да накарам това парче код да заработи и нестава и нестава:

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class practice{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        String regex="(?<barcode>[0-9]{2,})";

        String intace="4646";
        Pattern pattern=Pattern.compile(regex);
        Matcher matcher=pattern.matcher(intace);

        String tototo=matcher.group("barcode");
        System.out.print(tototo);


    }
}

 

Благодаря отново!

 

0
08/04/2020 12:50:49
thekoceto avatar thekoceto 31 Точки

Да се включа и аз. Това е регекса от твоето решение:

String regex = "^(@#+)([A-Z])(\\w{5,})([A-Z])(\\1)$";

Проблема е във тази (\\w{5,}) и тази (\\1) групи.

По условие имаш главна буква в началото, следват букви и цифри и накрая е отново главна буква и всичко това 6 и нагоре знака. Така написан ([A-Z])(\\w{5,})([A-Z]) взема 7 и нагоре. Второ \w е аналогично на [a-zA-Z0-9_]. Тук се взема освен всичко необходимо и знак _ а по условие не е така.

Не е по условие и повторението на първата група. Тя трябва да отговаря на същите условия като първата но може да е различна.

Според мен трябва да бъде:

String regex = "^(@#+)([A-Z][a-zA-Z0-9]{4,}[A-Z])(@#+)$";

Ето и моето решение: https://pastebin.com/3iPdSxpk

0
MartinBG avatar MartinBG 3862 Точки

Понеже оставихте възможност за въпроси ,искам да попитам за това : (?=[A-Z]) и това: (?<=[A-Z])

Първото е (positive) lookahead, а второто - (positive) lookbehind. Освен двете positive версии има и negative такива: 

(?=foo) Lookahead Asserts that what immediately follows the current position in the string is foo
(?<=foo) Lookbehind Asserts that what immediately precedes the current position in the string is foo
(?!foo) Negative Lookahead Asserts that what immediately follows the current position in the string is not foo
(?<!foo) Negative Lookbehind Asserts that what immediately precedes the current position in the string is not foo

 Ето малко повече по темата:

 

Също така пробвах какви ли не начини и варианти,комбинации да накарам това парче код да заработи и нестава и нестава

Създал си Pattern и от него създал и инициализирал Matcher инстанция, но не си стартирал същинското мачване и съответно няма как да извлечеш групата.

Има повече от един начин да направиш това - разгледай методите на Matcher класа, като в случая най-удачно изглежда използването на Matcher#matches:

public boolean matches()

Attempts to match the entire region against the pattern.

If the match succeeds then more information can be obtained via the , , and  methods.

Returns:

 if, and only if, the entire region sequence matches this matcher's pattern

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String regex = "(?<barcode>[0-9]{2,})";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher("1234");

        if (matcher.matches()) { // след този ред ще можем да достъпим групите
            String barcode = matcher.group("barcode");
            System.out.print(barcode);
        }
    }
}

 

0
08/04/2020 15:55:11
thekoceto avatar thekoceto 31 Точки

Тук намирам пролука да попитам нещо. Кода работи само ако го разкоменирам.

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String input = "@##Che4s6E@##";

        Matcher matcher = Pattern.compile("\\d").matcher(input);
        System.out.print("Product group: ");
//        matcher.find();
        if (matcher.matches()){
            while(matcher.find())
                System.out.print(matcher.group());
        } else
            System.out.print("00");
    }
}

Опитах се да ползвам .matches() но неуспешно. Кода работи само когат извикам първо метода find(). Предполагам аз не съм разбрал правилно работата му.

0
MartinBG avatar MartinBG 3862 Точки

@thekoceto

Matcher#matches обработва целият стринг наведнъж и връща true, ако е валиден (което в твоя пример ще е изпълнено само за стрингове от едно единствено число- напр "5").

Matcher#find сканира последователно стринга и спира при всяко едно съвпадение (в случая ще спира последователно върху всяко число).

0
08/04/2020 17:00:19
Sirakov4444 avatar Sirakov4444 11 Точки

Благодаря Ви колега!

0
Sirakov4444 avatar Sirakov4444 11 Точки

Благодаря Ви за отделеното време !

1
thekoceto avatar thekoceto 31 Точки

Благодаря @MartinBG

Аз търсих метод който да ми даде информация дали има поне едно съвпадение и след това с while(matcher.find()) да ги обходя. Неможах да намеря подобен метод.

0
Aleksandar.Hristov9 avatar Aleksandar.Hristov9 11 Точки

 string patternWords = @"([@]{1})([#]{1,})([[A-Z]{1})([a-zA-Z0-9]{4,})([A-Z]{1})([@])([#]{1,})";
 string patternNumbers = @"([0-9])";

Незнам дали е правилно но със тези я мипах със 100

            string patternWords = @"([@]{1})([#]{1,})([[A-Z]{1})([a-zA-Z0-9]{4,})([A-Z]{1})([@])([#]{1,})";
            string patternNumbers = @"([0-9])";
            int times = int.Parse(Console.ReadLine());

            Regex regexFirst = new Regex(patternWords);
            Regex regexSecond = new Regex(patternNumbers);
           
            for (int i = 1; i <= times; i++)
            {
                string input = Console.ReadLine();
                Match matchFirst = regexFirst.Match(input);
                Match matchSecond = regexSecond.Match(input);
                 if (!matchFirst.Success && !matchSecond.Success)
                {
                    Console.WriteLine("Invalid barcode");
                    continue;
                }
                else if (!matchSecond.Success)
                {
                    Console.WriteLine("Product group: 00");
                }
              
                else if (matchFirst.Success && matchSecond.Success)
                {
                    // Get a collection of matches.
                    MatchCollection matches = Regex.Matches(input, patternNumbers);
                    string concat = "";
                    // Use foreach-loop.
                    foreach (Match match in matches)
                    {
                        foreach (Capture capture in match.Captures)
                        {
                            concat += capture;
                        }
                    }
                    Console.WriteLine("Product group: " + concat);
                        //    string upperLetterss = matchSecond.Groups[1].Value;
                //    MatchCollection matches = Regex.Matches(input, patternNumbers);

                 //   string final = string.Concat("Product group: " + matches.Count);
                 //   Console.WriteLine(final);
                 //   continue;

                }
                  
             
            }
        }
    }
}

 

Кода не е нещо хубаво набързо написан :D 

0
08/04/2020 23:39:02
nadinka avatar nadinka 8 Точки

Здравейте,

Ще се възползвам, че има отворена тема във връзка с тази задача, за да помоля и аз за помощ, но моето решение е на JS.

Regex-ът ми работи в regex101, вкл. пробвах  и други регекси на хора, които казват, че с тях задачата им дава 100 от 100, а на мен Judge ми дава 60 точки. Не мога да разбера какъв е проблемът.

Това е кодът:

https://pastebin.com/1JM6DZAz

Благодаря предварително.

П.П. Махнах g и m флаговете и сега ми даде 80 точки :D 

А като ползвах регекса на колегата по-горе

^@#+(?=[A-Z])([A-Za-z0-9]{6,})(?<=[A-Z])@#+$

, даде 100. Някой може ли да каже какъв е проблемът в моя регекс?

 

 

0
09/04/2020 21:52:05