let's learn java language

I learning java language.

言語処理100本ノック 第2章: UNIXコマンドの基礎 10,11

10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

java

@Slf4j
public class App {
    public static void main(String[] args) {
        try {
            Path path = Paths.get(String.valueOf(args[0]));
            if (Files.isReadable(path)) {
                List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
                log.info("lines: {}", lines.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

java

@Slf4j
public class App {
    public static void main(String[] args) {
        if (args.length > 0) {
            try {
                Path path = Paths.get(String.valueOf(args[0]));
                if (Files.isReadable(path)) {
                    List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
                    log.info("lines: {}", lines.size());
                    List<String> lines2 = new ArrayList<>();
                    lines.forEach(l -> lines2.add(l.replace("\t", " ")));
                    System.out.println(String.join("\n", lines2));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

scraping in java. use selenium and chromedriver.

わけあって javascript でページロードするようなサイトのスクレイピングをして画像を取得したくなったのでしました。

scaj という名前でつくります。

  • build.gradle
group 'scaj'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'application'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.seleniumhq.selenium:selenium-server:3.0.1'
    compile 'org.slf4j:slf4j-simple:1.7.12'
    compile('com.squareup.okhttp3:okhttp:3.5.0')
    compile 'commons-codec:commons-codec:1.10'
    compileOnly('org.projectlombok:lombok:1.16.12')
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.2'
}

jar {
    baseName = 'scaj'
    version = '1.0'

    manifest {
        attributes 'Implementation-Title': 'Scaj', 'Implementation-Version': 1.0
        manifest.mainAttributes("Main-Class": "net.vg4.scaj.App")
    }

    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

mainClassName = "net.vg4.scaj.App"
package net.vg4.scaj;

import net.vg4.scaj.Tasks.DownloadImages;
import org.openqa.selenium.WebDriver;

/**
 * Created by 
 */
public class App {
    public static void main(String[] args) {
        DownloadImages sch = new DownloadImages();
        try {
            WebDriver driver = sch.apply();
            driver.quit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • DownloadImages.java
    public WebDriver apply() throws Exception {
        WebElement popup = driver.findElement(By.cssSelector("#..."));
        popup.click();
        WebElement menu = driver.findElement(By.cssSelector("#..."));
        menu.click();
        Wait<WebDriver> wait = new WebDriverWait(driver, 10);
        wait.until((ExpectedCondition<Boolean>) d -> d.getTitle().startsWith("..."));

        WebElement menu2 = driver.findElement(By.cssSelector("a[href='/...']"));
        menu2.click();

        Thread.sleep(1000);
        wait.until((ExpectedCondition<Boolean>) d -> d.getTitle().startsWith("..."));

        Thread.sleep(1000);
        WebElement loop = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
        loop.click();

        Thread.sleep(500);
        WebElement first = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
        log.info("first : {}", first);

        first.click();

        int count = 0;

        Wait<WebDriver> wait2 = new WebDriverWait(driver, 1);
        while (true) {

            Thread.sleep(500);
            WebElement pic = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
            log.info("pic : {}", pic);

            String src = pic.getAttribute("src");

            WebElement photonum = wait2.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
            try {
                downloadFileSync(src, photonum.getText());
                count++;
                if (count > 3000) {
                    log.info("over 3000");
                    return driver;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return driver;
            }

            try {
                WebElement next = wait2.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
                next.click();
                log.info("next : {}", next);
                continue;
            } catch (Exception e) {
                ;
            }
            WebElement close = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
            close.click();
            log.info("close : {}", close);
            Thread.sleep(1000);
            JavascriptExecutor jse = (JavascriptExecutor) driver;
            try {
                while (true) {
                    for (int i = 0; i < 100; i++) {
                        jse.executeScript("window.scrollBy(0,1000000)", "");
                        Thread.sleep(100);
                    }
                    try {
                        WebElement nextpage = wait2.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
                        nextpage.click();
                        log.info("nextpage : {}", nextpage);

                        Thread.sleep(1000);
                        WebElement first2 = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#...")));
                        log.info("first2 : {}", first2);

                        first2.click();

                        break;
                    } catch (Exception e) {
                        ;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }

        }

        return driver;
    }

とっても雑ですが、学びは、全部 wait でとったほうが楽だったことと、autopagirize 系はなにげに面倒だなってことでした。あと、途中で driver.get するのはダメだなってこと。

こういうのは ruby のほうが短く書けていいって思いながら書きました. kotlin にするとかもいいかもですね。

言語処理100本ノック 第1章: 準備運動 09

09. Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .")を与え,その実行結果を確認せよ.

java

package net.vg4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Main {
    private static String randomize(String str) {
        List<String> end = Arrays.asList(str.split(""));
        Random rand = new Random();
        for (String s : str.split("")) {
            int i = rand.nextInt(str.length());
            int j = rand.nextInt(str.length());
            String x = end.get(i);
            end.set(i, end.get(j));
            end.set(j, x);
        }
        return String.join("", end);
    }

    private static String getCenter(String str) {
        return str.substring(1, str.length() - 1);
    }

    public static void main(String[] args) {
        // write your code here
        String sample = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .";
        String[] sa = sample.split(" ");
        List<String> end = new ArrayList<>();
        for (String s : sa) {
            if (s.length() >= 4) {
                end.add(s.substring(0, 1) + randomize(getCenter(s)) + s.substring(s.length() - 1));
            } else {
                end.add(s);
            }
        }
        System.out.println(end);
    }
}

言語処理100本ノック 第1章: 準備運動 08

08. 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ.

  • 英小文字ならば(219 - 文字コード)の文字に置換
  • その他の文字はそのまま出力

この関数を用い,英語のメッセージを暗号化・復号化せよ.

java

package net.vg4;

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static String cipher(String str) {
        List<String> ret = new ArrayList<>();
        for (String s : str.split("")) {
            if (s.matches("[a-z]")) {
                try {
                    byte[] ba = s.getBytes("US-ASCII");
                    ba[0] = (byte) (219 - ba[0]);
                    ret.add(new String(ba, "US-ASCII"));
                } catch (Exception e) {
                    ;
                }
            } else {
                ret.add(s);
            }
        }
        return String.join("", ret);
    }

    public static void main(String[] args) {
        String sample = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .";

        String encoded = cipher(sample);
        System.out.println(encoded);
        String decoded = cipher(encoded);
        System.out.println(decoded);
    }
}

言語処理100本ノック 第1章: 準備運動 07

07. テンプレートによる文生成

引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y="気温", z=22.4として,実行結果を確認せよ

java

package net.vg4;

public class Main {

    public static String tmpl(String x, String y, String z) {
        return String.format("%s時の%sは%s", x, y, z);
    }

    public static void main(String[] args) {
        System.out.println(tmpl("12", "気温", "22.4"));
    }
}

言語処理100本ノック 第1章: 準備運動 06

06. 集合

"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,'se'というbi-gramがXおよびYに含まれるかどうかを調べよ.

java

package net.vg4;

import java.util.*;

class NGram {
    public List<List<String>> make(List<String> list, int n) {
        ArrayList<List<String>> alistlist = new ArrayList<>();
        for (int from = 0; from < list.size(); from++) {
            int to = from + n;
            if (to > list.size()) {
                to = list.size();
            }
            List<String> listr = list.subList(from, to);
            alistlist.add(listr);
        }
        return alistlist;
    }

    public List<List<String>> make(String str, int n) {
        return this.make(Arrays.asList(str.split("")), n);
    }
}

public class Main {
    public static void main(String[] args) {
        String sample1 = "paraparaparadise";
        String sample2 = "paragraph";

        NGram ngram = new NGram();

        List<List<String>> res1 = ngram.make(sample1, 2);
        Set<List<String>> xOrg = new HashSet<>(res1);

        List<List<String>> res2 = ngram.make(sample2, 2);
        Set<List<String>> y = new HashSet<>(res2);

        // 和集合
        {
            List<List<String>> x = new ArrayList<List<String>>(xOrg);
            x.addAll(y);
            System.out.println(x);
        }

        // 積集合
        {
            List<List<String>> x = new ArrayList<List<String>>(xOrg);
            x.retainAll(y);
            System.out.println(x);
        }

        // 差集合
        {
            List<List<String>> x = new ArrayList<List<String>>(xOrg);
            x.removeAll(y);
            System.out.println(x);
        }

        List<String> seed = Arrays.asList("s", "e");

        if (xOrg.contains(seed)) {
            System.out.println("including in x");
        }
        if (y.contains(seed)) {
            System.out.println("including in y");
        }

    }
}

言語処理100本ノック 第1章: 準備運動 05

05. n-gram

与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,"I am an NLPer"という文から単語bi-gram,文字bi-gramを得よ.

java

package net.vg4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class NGram {
    public List<List<String>> make(List<String> list, int n) {
        ArrayList<List<String>> alistlist = new ArrayList<>();
        for (int from = 0; from < list.size(); from++) {
            int to = from + n;
            if (to > list.size()) {
                to = list.size();
            }
            List<String> listr = list.subList(from, to);
            alistlist.add(listr);
        }
        return alistlist;
    }

    public List<List<String>> make(String str, int n) {
        return this.make(Arrays.asList(str.split("")), n);
    }
}

public class Main {
    public static void main(String[] args) {
        String sample = "I am an NLPer";
        NGram ngram = new NGram();
        List<List<String>> res = ngram.make(sample, 2);
        System.out.println(res);
        List<String> list = Arrays.asList(sample.split(" "));
        List<List<String>> res2 = ngram.make(list, 2);
        System.out.println(res2);
    }
}

sublist は例外でとれば毎回 if しなくていいって思ったけど、例外前提ってのはよくないときいて。

言語処理100本ノック 第1章: 準備運動 04

04. 元素記号

"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

java

String str = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.";
String[] stra = str.split(" ");
List<Integer> list = List.of(1, 5, 6, 7, 8, 9, 15, 16, 19);
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < stra.length; i++ ) {
    int ki = 2;
    if (list.contains(i+1)) {
        ki = 1;
    }
    String key = stra[i].substring(0, ki);
    map.put(key, i+1);
}

System.out.println(map);

うーん。。。いかにも遅そう

言語処理100本ノック 第1章: 準備運動 02, 03

ちなみに、jdk9 の jshell をつかってます。 https://jdk9.java.net/download/

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

java

String str1 = "パトカー";
String str2 = "タクシー";
Iterator<String> it1 = List.of(str1.split("")).iterator();
Iterator<String> it2 = List.of(str2.split("")).iterator();
ArrayList<String> sa = new ArrayList<>();
while (it1.hasNext() && it2.hasNext()){
    sa.add(it1.next());
    sa.add(it2.next());
}
System.out.println(String.join("", sa));

Streams.zip はどこへ行ったんだろう?

String str1 = "パトカー";
String str2 = "タクシー";
ArrayList<String> sa = new ArrayList<>();
Streams.zip(List.of(str1.split("")).stream(), List.of(str2.split("")).stream(), (c1, c2) -> sa.add(c1), sa.add(c2));

こんなふうになるつもりだったのだが...


03. 円周率

"Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.

java

String sample = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.";
Integer[] ia = Arrays.stream(sample.split(" ")).map(e -> e.length()).toArray(e -> new Integer[e]);

toArray がなんかムズいな。

言語処理100本ノック 第1章: 準備運動 00, 01

00. 文字列の逆順

文字列"stressed"の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.

java

new StringBuilder("stressed").reverse().toString();

ruby(参考)

"stressed".reverse

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.

java

StringBuilder sb = new StringBuilder("パタトクカシーー");
StringJoiner sj = new StringJoiner("");
List<Integer> list = Arrays.asList(1, 3, 5, 7);
list.stream().forEach(e -> sj.add(String.valueOf(sb.charAt(e))));
sj.toString();