DIO ブートキャンプで本当に素晴らしいと思うことの 1 つは、トレイル中にエディターが近くにあり、いくつかの条件を満たした状態でコードの演習がいくつか行われることです。ちょっとHackerRankっぽい雰囲気。これは、理論的な部分で得た知識を統合するのに役立ち、プロジェクト チャレンジのような複雑なアプローチではないため、本当に素晴らしいものです。論理的推論と言語の知識をテストするための、より単純化されたものです。 HackerRank と同様に、既製のスニペットがいくつか提供され、それに基づいてロジックを開発します。
今週は本当に大変な週だったので、私が何とかできたのは、モジュール「テレフォニー サービスの探索」で提案された 2 つの課題を解決することだけでした。このブートキャンプのスポンサーは Claro であるため、多くのテーマは通信風味になります。
電気通信事業者は、携帯電話、固定電話、ブロードバンド、有料テレビの 4 種類のサービスを提供します。顧客サービスを円滑に行うためには、特定の顧客が特定のサービスを契約しているかどうかを確認するプログラムを実装する必要があります。たとえば、顧客がコールセンターに電話してサービスについて言及したとき、対応者はそのサービスが顧客によって契約されているかどうかをすぐに確認できなければなりません。
2 つの文字列: 1 つはアプリケーションがチェックするサービス (モバイル、固定、ブロードバンド、TV など) です。 2 番目には、顧客の名前と所有している製品をカンマで区切って入力する必要があります (Alice、モバイル、固定)
顧客が最初のエントリで説明されているサービスを契約している場合、アプリケーションは「はい」と表示する必要があります。それ以外の場合は、「いいえ」と表示する必要があります。
Entrada | Saída |
---|---|
movel Alice,movel,fixa |
Sim |
fixa Bob,movel,tv |
Nao |
tv Carol,movel,fixa,tv |
Sim |
import java.util.Scanner; public class VerificacaoServico { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Entrada do serviço a ser verificado String servico = scanner.nextLine().trim(); // Entrada do nome do cliente e os serviços contratados String entradaCliente = scanner.nextLine().trim(); // Separando o nome do cliente e os serviços contratados String[] partes = entradaCliente.split(","); String nomeCliente = partes[0]; boolean contratado = false; // TODO: Verifique se o serviço está na lista de serviços contratados scanner.close(); } }
これは比較的簡単な課題です。アプリケーションは、配列に変換されたコンマで区切られた文字列を受け取ります。その中に別のユーザー入力と一致する文字列があるかどうかを確認する必要があります。これは、クライアントが持っているかどうかを確認したいサービスです。簡単ですよね?
JavaScript と C# の経験がある私の場合は、チェッカー メソッド (Array.includes() や List.Contains() など) を使用するだけです。右?違います。
Java では、Array クラスにこのようなメソッドはありません。これは、実装が低レベル言語 (C など) で行われることに非常に近いため、低レベル言語は単純で効率的なデータ構造でなければならないことが原因である可能性があります。どうやら、このタイプのクエリは、この構造の重要な機能の一部ではありません。
この情報を知ったときはショックでした。 Java は私に何を期待しているのでしょうか? ループを作成し、各要素が探している項目と一致するかどうかを手動で確認するということですか?兄さん、私はフルタイムで働いていて、2歳未満の娘がいて、まだJavaを勉強しています。そんな時間はないよ、
しかし、Java 8 以降では配列をリストに変換でき、これには .contains() メソッドがあることがわかりました。したがって、この問題を解決するには、部品配列をリストに変換し、サービスに渡された文字列がこのリスト内に存在するかどうかを確認するだけです。
存在する場合は Yes を出力し、存在しない場合は No を出力します。
import java.util.Arrays; import java.util.Scanner; public class VerificacaoServico { public static void main(String[] args) { //... // TODO: Verifique se o serviço está na lista de serviços contratados contratado = Arrays.asList(partes).contains(servico); System.out.println(contratado ? "Sim" : "Nao"); scanner.close(); } }
これで演習は完了ですが、調査中に、Java 8 以降、より簡単な方法で、より機能的なアプローチでデータのコレクションを操作するのに役立つ抽象化が存在することを発見しました。 JavaScript: ストリーム。
リストの場合と同様に、ベクトルをストリームに変換し、その中に存在する要素のいずれかがサービスで渡されたものに対応するかどうかを確認できます。
import java.util.Arrays; import java.util.Scanner; public class VerificacaoServico { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Entrada do serviço a ser verificado String servico = scanner.nextLine().trim(); // Entrada do nome do cliente e os serviços contratados String entradaCliente = scanner.nextLine().trim(); // Separando o nome do cliente e os serviços contratados String[] partes = entradaCliente.split(","); String nomeCliente = partes[0]; boolean contratado = false; contratado = Arrays.stream(partes).anyMatch(servico::equals); System.out.println(contratado ? "Sim" : "Nao"); scanner.close(); } }
p と servico が同じ値を持つだけでなく、メモリの同じアドレスを指しているかどうか (つまり、実際に同じオブジェクトであるかどうか) をチェックすることもできました。通常、文字列を扱う場合、この比較は、値が等しい場合でも false を返します。つまり、偽陰性です。したがって、servico::equals を使用した比較の方が適切です。これは、JavaScript の等価比較器 (==) とほぼ同様に、2 つの要素間の 値 のみを比較するためです。
この変更により、演習は完了したと判断できます。残っているのは、テストを実行して合格するかどうかを確認することです:
良すぎます。
この演習により、Java について不満を言うもう 1 つの理由ができました。それは、lambda 構文です。二重矢印 (=>) の代わりに単一矢印 (->) を使用するのがとても気になります。
電気通信会社の顧客がサービスの完全な組み合わせを契約しているかどうかを確認するシステムを実装します。完全なコンボには、同社が提供する 3 つの主要サービス (携帯電話、ブロードバンド、有料テレビ) が含まれます。システムは、顧客が契約したサービスのリストを読み取り、必要なサービスがすべて含まれているかどうかを判断する必要があります。 3 つのサービスがすべて存在する場合、システムは「Complete Combo」を返すはずです。いずれかのサービスが欠落している場合、システムは「不完全なコンボ」を返します。
顧客が契約したサービスをカンマで区切って含む文字列。可能な値は、モバイル、ブロードバンド、TV です。
クライアントがすべてのサービスを契約している場合は Complete Combo を含む文字列、それ以外の場合は Incomplete Combo を含む文字列。
Entrada | Saída |
---|---|
movel,banda larga,tv | Combo Completo |
movel,tv | Combo Incompleto |
banda larga,tv,movel | Combo Completo |
import java.util.Scanner; public class VerificacaoComboCompleto { // Função para verificar se o cliente contratou um combo completo public static String verificarComboCompleto(String[] servicosContratados) { // Variáveis booleanas para verificar a contratação de cada serviço boolean movelContratado = false; boolean bandaLargaContratada = false; boolean tvContratada = false; // TODO: Itere sobre os serviços contratados for (String servico : servicosContratados) { } // TODO: Verifique se todos os serviços foram contratados if () { return "Combo Completo"; } else { return "Combo Incompleto"; } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Solicitando ao usuário a lista de serviços contratados String input = scanner.nextLine(); // Convertendo a entrada em uma lista de strings String[] servicosContratados = input.split(","); // Verificando se o cliente contratou um combo completo String resultado = verificarComboCompleto(servicosContratados); // Exibindo o resultado System.out.println(resultado); // Fechando o scanner scanner.close(); } }
De novo, esse é um desafio simples. Para chegar no resultado, apenas alguns passos precisam ser seguidos:
for (String servico : servicosContratados) { if(servico.equals("movel")) movelContratado = true; if(servico.equals("bandaLarga")) bandaLargaContratada = true; if(servico.equals("tv")) tvContratada = true; }
E preenchemos a condição do nosso if:
if (movelContratado && bandaLargaContratada && tvContratada) { return "Combo Completo"; } else { return "Combo Incompleto";
Assim como no primeiro, com essas adições o desafio pode ser considerado como completo, mas esses ifs, um seguido do outro me incomoda um pouco. Podemos alterar isso pra um switch pra ficar menos feio:
for (String servico : servicosContratados) { switch (servico) { case "movel": movelContratado = true; break; case "banda larga": bandaLargaContratada = true; break; case "tv": tvContratada = true; break; default: System.out.println("Serviço inválido."); break; } }
Há quem diga que os ifs são de mais fácil leitura e que o ganho que a otimização traria para um switch tão pequeno como esse é desprezível. Outros diriam que eu tenho pouca consistência interna, reclamando de checar manualmente strings em um exercício e fazendo sem um pio em outro.
Pra essas pessoas eu digo:
O código final ficaria então:
import java.util.Scanner; public class VerificacaoComboCompleto { // Função para verificar se o cliente contratou um combo completo public static String verificarComboCompleto(String[] servicosContratados) { // Variáveis booleanas para verificar a contratação de cada serviço boolean movelContratado = false; boolean bandaLargaContratada = false; boolean tvContratada = false; for (String servico : servicosContratados) { switch (servico) { case "movel": movelContratado = true; break; case "banda larga": bandaLargaContratada = true; break; case "tv": tvContratada = true; break; default: System.out.println("Serviço inválido."); break; } } if (movelContratado && bandaLargaContratada && tvContratada) { return "Combo Completo"; } else { return "Combo Incompleto"; } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Solicitando ao usuário a lista de serviços contratados String input = scanner.nextLine(); // Convertendo a entrada em uma lista de strings String[] servicosContratados = input.split(","); // Verificando se o cliente contratou um combo completo String resultado = verificarComboCompleto(servicosContratados); // Exibindo o resultado System.out.println(resultado); // Fechando o scanner scanner.close(); } }
Que, ao rodar a suite de testes, nos mostra que deu tudo certo:
O código desses (e dos demais) desafios está aqui.
Então é isso, pessoal. Até a próxima!
以上がコード チャレンジ - テレフォニー サービスの探索の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。