From fcc23b4f3d284b1c7d8b083e6c1d6267429b41fb Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 22 Sep 2016 19:57:30 +0800 Subject: [PATCH 01/96] add guice dependence --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 5807811..eed921d 100644 --- a/pom.xml +++ b/pom.xml @@ -259,5 +259,11 @@ 4.0.33.Final + + com.google.inject + guice + 4.1.0 + + From 3b6835592e6bb946f18d870a5abe8cdbe0c71d0a Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 31 Oct 2016 20:49:41 +0800 Subject: [PATCH 02/96] add examples --- pom.xml | 11 ++++ .../java/org/wcong/test/guice/GuiceTest.java | 63 +++++++++++++++++++ .../org/wcong/test/guice/MapBinderTest.java | 42 +++++++++++++ .../org/wcong/test/guice/SetBinderTest.java | 33 ++++++++++ 4 files changed, 149 insertions(+) create mode 100644 src/main/java/org/wcong/test/guice/GuiceTest.java create mode 100644 src/main/java/org/wcong/test/guice/MapBinderTest.java create mode 100644 src/main/java/org/wcong/test/guice/SetBinderTest.java diff --git a/pom.xml b/pom.xml index eed921d..ec52e13 100644 --- a/pom.xml +++ b/pom.xml @@ -265,5 +265,16 @@ 4.1.0 + + com.google.inject.extensions + guice-servlet + 4.1.0 + + + com.google.inject.extensions + guice-multibindings + 4.1.0 + + diff --git a/src/main/java/org/wcong/test/guice/GuiceTest.java b/src/main/java/org/wcong/test/guice/GuiceTest.java new file mode 100644 index 0000000..3d315bb --- /dev/null +++ b/src/main/java/org/wcong/test/guice/GuiceTest.java @@ -0,0 +1,63 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; +import com.google.inject.matcher.Matcher; +import com.google.inject.spi.ProvisionListener; +import com.google.inject.spi.TypeEncounter; +import com.google.inject.spi.TypeListener; + +/** + * @author wcong + * @since 2016/10/29 + */ +public class GuiceTest { + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(BindClass.class).toInstance(new BindClass()); + bindListener(new MyMatcher(), new MyTypeListener()); + bindListener(new MyMatcher(), new MyProvisionListener()); + } + }); + System.out.println(injector.getInstance(BindClass.class).message); + } + + public static class BindClass { + public String message = "hello world"; + } + + public static class MyMatcher implements Matcher { + + public boolean matches(Object o) { + return true; + } + + public Matcher and(Matcher other) { + return null; + } + + public Matcher or(Matcher other) { + return null; + } + } + + public static class MyTypeListener implements TypeListener { + + public void hear(TypeLiteral type, TypeEncounter encounter) { + System.out.println("hehehe"); + } + } + + public static class MyProvisionListener implements ProvisionListener { + + public void onProvision(ProvisionInvocation provision) { + System.out.println("hahaha"); + } + } + +} diff --git a/src/main/java/org/wcong/test/guice/MapBinderTest.java b/src/main/java/org/wcong/test/guice/MapBinderTest.java new file mode 100644 index 0000000..96ebdf6 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/MapBinderTest.java @@ -0,0 +1,42 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.multibindings.MapBinder; + +import java.util.Map; + +/** + * @author wcong + * @since 2016/10/31 + */ +public class MapBinderTest { + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + MapBinder mapBinder = MapBinder.newMapBinder(binder(), String.class, String.class); + mapBinder.addBinding("hello").toInstance("world"); + binder().bind(MapContainer.class).asEagerSingleton(); + } + }); + MapContainer mapContainer = injector.getInstance(MapContainer.class); + System.out.println(mapContainer.toString()); + } + + public static class MapContainer { + + private Map data; + + @Inject + public MapContainer(Map data) { + this.data = data; + } + + public String toString() { + return data.toString(); + } + } +} diff --git a/src/main/java/org/wcong/test/guice/SetBinderTest.java b/src/main/java/org/wcong/test/guice/SetBinderTest.java new file mode 100644 index 0000000..5d52762 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/SetBinderTest.java @@ -0,0 +1,33 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.google.inject.multibindings.Multibinder; + +import java.util.List; +import java.util.Set; + +/** + * @author wcong + * @since 2016/10/31 + */ +public class SetBinderTest { + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + Multibinder multibinder = Multibinder.newSetBinder(binder(), String.class); + multibinder.addBinding().toInstance("hello"); + multibinder.addBinding().toInstance("world"); + } + }); + Set stringList = injector.getInstance(Key.get(new TypeLiteral>() { + })); + System.out.println(stringList); + } + +} From 359e1467d644d4940eee0a27c7e646b5cf06d519 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 2 Nov 2016 19:48:19 +0800 Subject: [PATCH 03/96] add dagger --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index ec52e13..82bb49a 100644 --- a/pom.xml +++ b/pom.xml @@ -276,5 +276,17 @@ 4.1.0 + + com.google.dagger + dagger + 2.7 + + + com.google.dagger + dagger-compiler + 2.7 + true + + From bd78436f9407831e7c33b920cfc88822dfdf3490 Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 3 Nov 2016 11:08:04 +0800 Subject: [PATCH 04/96] add DaggerTest --- .../org/wcong/test/dagger/DaggerTest.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/main/java/org/wcong/test/dagger/DaggerTest.java diff --git a/src/main/java/org/wcong/test/dagger/DaggerTest.java b/src/main/java/org/wcong/test/dagger/DaggerTest.java new file mode 100644 index 0000000..3d757d0 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/DaggerTest.java @@ -0,0 +1,81 @@ +package org.wcong.test.dagger; + +import dagger.Binds; +import dagger.Component; +import dagger.Lazy; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * @author wcong + * @since 2016/11/2 + */ +public class DaggerTest { + public static void main(String[] args) { + Coffee coffee = DaggerDaggerTest_Coffee.builder().build(); + coffee.maker().brew(); + } + + @Singleton + @Component(modules = { DripCoffeeModule.class }) + public interface Coffee { + CoffeeMaker maker(); + } + + @Module(includes = PumpModule.class) + static class DripCoffeeModule { + @Provides + @Singleton + Heater provideHeater() { + return new ElectricHeater(); + } + } + + @Module + abstract class PumpModule { + @Binds + abstract Pump providePump(Thermosiphon pump); + } + + static class CoffeeMaker { + Lazy heater; + + Pump pump; + + @Inject + CoffeeMaker(Lazy heater, Pump pump) { + this.heater = heater; + this.pump = pump; + } + + public void brew() { + pump.pump(); + } + } + + interface Heater { + } + + interface Pump { + void pump(); + } + + static class Thermosiphon implements Pump { + private final Heater heater; + + @Inject + Thermosiphon(Heater heater) { + this.heater = heater; + } + + public void pump() { + System.out.println(heater); + } + } + + static class ElectricHeater implements Heater { + } +} From a12a8f8a743d8401d397ac50f274b78caf21b2c5 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 7 Nov 2016 16:52:31 +0800 Subject: [PATCH 05/96] save something --- pom.xml | 15 ++++ .../wcong/test/dagger/CircleBindingTest.java | 72 +++++++++++++++++ .../annotation/AnnotationProcessorTest.java | 81 +++++++++++++++++++ .../test/dagger/annotation/MyAnnotation.java | 17 ++++ 4 files changed, 185 insertions(+) create mode 100644 src/main/java/org/wcong/test/dagger/CircleBindingTest.java create mode 100644 src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java create mode 100644 src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java diff --git a/pom.xml b/pom.xml index 82bb49a..002b2af 100644 --- a/pom.xml +++ b/pom.xml @@ -287,6 +287,21 @@ 2.7 true + + com.google.auto + auto-common + 0.8 + + + com.google.auto.service + auto-service + 1.0-rc2 + + + com.google.auto.value + auto-value + 1.3 + diff --git a/src/main/java/org/wcong/test/dagger/CircleBindingTest.java b/src/main/java/org/wcong/test/dagger/CircleBindingTest.java new file mode 100644 index 0000000..d126bc3 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/CircleBindingTest.java @@ -0,0 +1,72 @@ +package org.wcong.test.dagger; + +import dagger.Binds; +import dagger.Component; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * @author wcong + * @since 2016/11/7 + */ +public class CircleBindingTest { + public static void main(String[] args) { + MyComponent myComponent = DaggerCircleBindingTest_MyComponent.builder().build(); + myComponent.getExportClass().print(); + } + + @Singleton + @Component(modules = { MyBindModule.class, MyProvidesModule.class }) + interface MyComponent { + ExportClass getExportClass(); + } + + static class ExportClass { + private final MyClass myClass; + + + @Inject + public ExportClass(MyClass myClass) { + this.myClass = myClass; + } + + public void print(){ + + } + } + + @Module + static class MyProvidesModule { + @Provides + MyParam getMyParam() { + return new MyParam(); + } + } + + @Module + abstract class MyBindModule { + + @Binds + abstract MyClass myClass(MySubClass a); + } + + static class MyClass { + + } + + static class MySubClass extends MyClass { + + private final MyParam myParam; + + @Inject + public MySubClass(MyParam myParam) { + this.myParam = myParam; + } + } + + static class MyParam { + } +} diff --git a/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java b/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java new file mode 100644 index 0000000..6723831 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java @@ -0,0 +1,81 @@ +package org.wcong.test.dagger.annotation; + +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeTranslator; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaFileObject; +import java.util.Set; + +/** + * @author wcong + * @since 2016/11/4 + */ +public class AnnotationProcessorTest { + public static void main(String[] args) { + + } + + @SupportedAnnotationTypes("org.wcong.test.dagger.annotation.MyAnnotation") + static class MyProcessor extends AbstractProcessor { + + private Trees trees; + + public void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + trees = Trees.instance(processingEnv); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + + final TreePathScanner scanner = new TreePathScanner() { + public Trees visitClass(final ClassTree classTree, final CompilationUnitTree unitTree) { + if (unitTree instanceof JCTree.JCCompilationUnit) { + final JCTree.JCCompilationUnit compilationUnit = (JCTree.JCCompilationUnit) unitTree; + if (compilationUnit.sourcefile.getKind() == JavaFileObject.Kind.SOURCE) { + compilationUnit.accept(new TreeTranslator() { + public void visitVarDef(final JCTree.JCVariableDecl tree) { + super.visitVarDef(tree); + if ((tree.mods.flags & Flags.FINAL) == 0) { + tree.mods.flags |= Flags.FINAL; + + } + } + public void visitClassDef(JCTree.JCClassDecl tree) { + super.visitClassDef(tree); + //tree.implementing = tree.implementing.add(new JCTree.JCClassDecl()); + } + }); + } + + } + return trees; + + } + }; + Set elements = roundEnv.getElementsAnnotatedWith(MyAnnotation.class); + for (Element element : elements) { + final TreePath path = trees.getPath(element); + scanner.scan(path, path.getCompilationUnit()); + } + return true; + } + } + + @MyAnnotation + static class ParseClass { + + } +} diff --git a/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java b/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java new file mode 100644 index 0000000..7d8c474 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java @@ -0,0 +1,17 @@ +package org.wcong.test.dagger.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author wcong + * @since 2016/11/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Documented +@Target(ElementType.TYPE) +public @interface MyAnnotation { +} From e7596ceefda6dff5e9611b1ed0481c182a6c404b Mon Sep 17 00:00:00 2001 From: wcong Date: Fri, 11 Nov 2016 17:39:52 +0800 Subject: [PATCH 06/96] java file test --- pom.xml | 16 ++++++-- .../org/wcong/test/guice/TwoModuleTest.java | 39 +++++++++++++++++++ .../java/org/wcong/test/oep/JavaFileTest.java | 15 +++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/wcong/test/guice/TwoModuleTest.java create mode 100644 src/main/java/org/wcong/test/oep/JavaFileTest.java diff --git a/pom.xml b/pom.xml index 002b2af..1f35b15 100644 --- a/pom.xml +++ b/pom.xml @@ -297,10 +297,20 @@ auto-service 1.0-rc2 + + + + + + + com.squareup + javapoet + 1.7.0 + - com.google.auto.value - auto-value - 1.3 + com.google.googlejavaformat + google-java-format + 1.1 diff --git a/src/main/java/org/wcong/test/guice/TwoModuleTest.java b/src/main/java/org/wcong/test/guice/TwoModuleTest.java new file mode 100644 index 0000000..88a0f66 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/TwoModuleTest.java @@ -0,0 +1,39 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Singleton; + +/** + * Created by wcong on 2016/9/19. + */ +public class TwoModuleTest { + + public interface Print { + void print(); + } + + @Singleton + public static class HelloPrint implements Print { + + public void print() { + System.out.println("hello"); + } + } + + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(Print.class).to(HelloPrint.class); + } + }); + Print print = injector.getInstance(Print.class); + System.out.println(print); + print = injector.getInstance(Print.class); + System.out.println(print); + } + +} diff --git a/src/main/java/org/wcong/test/oep/JavaFileTest.java b/src/main/java/org/wcong/test/oep/JavaFileTest.java new file mode 100644 index 0000000..9c1646f --- /dev/null +++ b/src/main/java/org/wcong/test/oep/JavaFileTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.oep; + +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.TypeSpec; + +/** + * Created by wcong on 2016/11/11. + */ +public class JavaFileTest { + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.oep", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } +} From b00866010b590ceaa0b1bdd7a78d99038a5275ec Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 13 Nov 2016 21:48:55 +0800 Subject: [PATCH 07/96] add java file --- .../java/org/wcong/test/oep/JavaFileTest.java | 15 ----- .../org/wcong/test/poet/JavaFileTest.java | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+), 15 deletions(-) delete mode 100644 src/main/java/org/wcong/test/oep/JavaFileTest.java create mode 100644 src/main/java/org/wcong/test/poet/JavaFileTest.java diff --git a/src/main/java/org/wcong/test/oep/JavaFileTest.java b/src/main/java/org/wcong/test/oep/JavaFileTest.java deleted file mode 100644 index 9c1646f..0000000 --- a/src/main/java/org/wcong/test/oep/JavaFileTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.wcong.test.oep; - -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.TypeSpec; - -/** - * Created by wcong on 2016/11/11. - */ -public class JavaFileTest { - public static void main(String[] args) { - TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); - JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.oep", typeSpecBuilder.build()); - System.out.println(javaFileBuilder.build().toString()); - } -} diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java new file mode 100644 index 0000000..44bd5d2 --- /dev/null +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -0,0 +1,56 @@ +package org.wcong.test.poet; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import javax.lang.model.element.Modifier; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wcong on 2016/11/11. + */ +public class JavaFileTest { + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addField(makeFieldSpec()); + typeSpecBuilder.addMethods(makeMethodSpec()); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } + + static AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); + builder.addMember("hello", codeBlockBuilder.build()); + return builder.build(); + } + + static FieldSpec makeFieldSpec() { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + return fileSpecBuilder.build(); + } + + static List makeMethodSpec() { + List methodSpecList = new ArrayList(); + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + methodSpecList.add(getMethodSpecBuilder.build()); + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + setMethodSpecBuilder.addParameter(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + methodSpecList.add(setMethodSpecBuilder.build()); + return methodSpecList; + } +} From 8e0e78fd7d39ef9d43b748de74abb192b6ed1e7c Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 14 Nov 2016 21:14:37 +0800 Subject: [PATCH 08/96] basic doc --- doc/dagger/JavaPoet.md | 5 +++++ src/main/java/org/wcong/test/poet/JavaFileTest.java | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 doc/dagger/JavaPoet.md diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md new file mode 100644 index 0000000..41a052b --- /dev/null +++ b/doc/dagger/JavaPoet.md @@ -0,0 +1,5 @@ +### 前言 +最近在用[dagger](https://github.com/google/dagger)开发应用,这里介绍一下dagger的实现原理 +### JavaPoet +主要功能 +### 样例 \ No newline at end of file diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java index 44bd5d2..a00d0f4 100644 --- a/src/main/java/org/wcong/test/poet/JavaFileTest.java +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -6,6 +6,7 @@ import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; @@ -48,7 +49,8 @@ static List makeMethodSpec() { MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); setMethodSpecBuilder.returns(TypeName.VOID); - setMethodSpecBuilder.addParameter(TypeName.get(String.class), "hello"); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); methodSpecList.add(setMethodSpecBuilder.build()); return methodSpecList; From e310cf1e5dcac22583e9ef6de5977fc54e1fc3f1 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 15 Nov 2016 20:27:23 +0800 Subject: [PATCH 09/96] add controller flow --- .../java/org/wcong/test/poet/JavaFileTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java index a00d0f4..b7cf16d 100644 --- a/src/main/java/org/wcong/test/poet/JavaFileTest.java +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -36,16 +36,19 @@ static AnnotationSpec makeAnnotationSpec() { static FieldSpec makeFieldSpec() { FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); return fileSpecBuilder.build(); } static List makeMethodSpec() { List methodSpecList = new ArrayList(); + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); getMethodSpecBuilder.returns(TypeName.get(String.class)); getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); methodSpecList.add(getMethodSpecBuilder.build()); + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); setMethodSpecBuilder.returns(TypeName.VOID); @@ -53,6 +56,17 @@ static List makeMethodSpec() { setMethodSpecBuilder.addParameter(parameterBuilder.build()); setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); methodSpecList.add(setMethodSpecBuilder.build()); + + MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); + toStringBuilder.addModifiers(Modifier.PUBLIC); + toStringBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); + toStringCodeBuilder.beginControlFlow("if( hello != null )"); + toStringCodeBuilder.add(CodeBlock.of("return \"hello\"+hello;")); + toStringCodeBuilder.endControlFlow(); + toStringBuilder.addCode(toStringCodeBuilder.build()); + methodSpecList.add(toStringBuilder.build()); + return methodSpecList; } } From 64993fa827e5ef021097e37ac5a6e2e82fc0d4b5 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 15 Nov 2016 21:01:01 +0800 Subject: [PATCH 10/96] save --- doc/dagger/JavaPoet.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md index 41a052b..a118877 100644 --- a/doc/dagger/JavaPoet.md +++ b/doc/dagger/JavaPoet.md @@ -1,5 +1,11 @@ ### 前言 -最近在用[dagger](https://github.com/google/dagger)开发应用,这里介绍一下dagger的实现原理 +最近在用[dagger](https://github.com/google/dagger)开发应用,dagger是google在[square](https://github.com/square/dagger)的基础上去反射的依赖注入框架。 +dagger会根据定义的直接在编译阶段自动生成依赖注入的代码,来减少运行期间反射的开销。 +dagger依赖了square的JavaPoet和JavaFormat来实现编译代码。这里主要介绍下JavaPoet。 + ### JavaPoet -主要功能 +``` +Use beautiful Java code to generate beautiful Java code +``` +JavaPoet定义了一系列类来描述java ### 样例 \ No newline at end of file From 18d3e689789f740c69da397c6d3dda7d3c2d0d44 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 15 Nov 2016 23:36:45 +0800 Subject: [PATCH 11/96] add doc --- doc/dagger/JavaPoet.md | 84 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md index a118877..3302d64 100644 --- a/doc/dagger/JavaPoet.md +++ b/doc/dagger/JavaPoet.md @@ -4,8 +4,88 @@ dagger会根据定义的直接在编译阶段自动生成依赖注入的代码 dagger依赖了square的JavaPoet和JavaFormat来实现编译代码。这里主要介绍下JavaPoet。 ### JavaPoet +JavaPoet这样定义自己的项目. ``` Use beautiful Java code to generate beautiful Java code ``` -JavaPoet定义了一系列类来描述java -### 样例 \ No newline at end of file +所以JavaPoet定义了一系列类来尽可能优雅的描述java源文件的结构.通过下面的maven定义可以引用JavaPoet包 +``` + + com.squareup + javapoet + 1.7.0 + +``` +观察JavaPoet的代码主要的接口可以分为以下几种 + +* Spec + * AnnotationSpec + * FieldSpec + * MethodSpec + * ParameterSpec + * TypeSpec + * +* Name + * TypeName + * ArrayTypeName + * ClassName + * ParameterizedTypeName + * TypeVariableName + * WildcardTypeName +* CodeBlock +* CodeWriter +* JavaFile +* Util +* NameAllocator + +### 使用样例 +这里使用JavaPoet定义了一个简单的Java类,完整的代码放在[Github](). + +``` java + public class JavaFileTest { + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addField(makeFieldSpec()); + typeSpecBuilder.addMethods(makeMethodSpec()); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } + static AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); + builder.addMember("hello", codeBlockBuilder.build()); + return builder.build(); + } + static FieldSpec makeFieldSpec() { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); + return fileSpecBuilder.build(); + } + static List makeMethodSpec() { + List methodSpecList = new ArrayList(); + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + methodSpecList.add(getMethodSpecBuilder.build()); + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + methodSpecList.add(setMethodSpecBuilder.build()); + MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); + toStringBuilder.addModifiers(Modifier.PUBLIC); + toStringBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); + toStringCodeBuilder.beginControlFlow("if( hello != null )"); + toStringCodeBuilder.add(CodeBlock.of("return \"hello\"+hello;")); + toStringCodeBuilder.endControlFlow(); + toStringBuilder.addCode(toStringCodeBuilder.build()); + methodSpecList.add(toStringBuilder.build()); + return methodSpecList; + } + } +``` \ No newline at end of file From 66efe2dec114e10a8844f1e82f726d321efc7643 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 16 Nov 2016 14:30:14 +0800 Subject: [PATCH 12/96] save --- doc/dagger/JavaPoet.md | 37 +++++++------- .../org/wcong/test/poet/JavaFileTest.java | 48 +++++++++++-------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md index 3302d64..53af650 100644 --- a/doc/dagger/JavaPoet.md +++ b/doc/dagger/JavaPoet.md @@ -1,44 +1,41 @@ ### 前言 最近在用[dagger](https://github.com/google/dagger)开发应用,dagger是google在[square](https://github.com/square/dagger)的基础上去反射的依赖注入框架。 -dagger会根据定义的直接在编译阶段自动生成依赖注入的代码,来减少运行期间反射的开销。 -dagger依赖了square的JavaPoet和JavaFormat来实现编译代码。这里主要介绍下JavaPoet。 +dagger会根据定义的注解在编译阶段自动生成依赖注入的代码,来减少运行期间反射的开销。 +dagger依赖了JavaPoet和JavaFormat来实现编译代码,这里主要介绍下JavaPoet的内容和使用。 ### JavaPoet -JavaPoet这样定义自己的项目. +JavaPoet这样定义自己的项目。 ``` Use beautiful Java code to generate beautiful Java code ``` -所以JavaPoet定义了一系列类来尽可能优雅的描述java源文件的结构.通过下面的maven定义可以引用JavaPoet包 -``` - - com.squareup - javapoet - 1.7.0 - -``` -观察JavaPoet的代码主要的接口可以分为以下几种 +所以JavaPoet定义了一系列类来尽可能优雅的描述java源文件的结构。观察JavaPoet的代码主要的接口可以分为以下几种: -* Spec +* Spec 用来描述Java中基本的元素,包括类型,注解,字段,方法和参数 * AnnotationSpec * FieldSpec * MethodSpec * ParameterSpec * TypeSpec - * -* Name +* Name 用来描述类型的引用,包括Void,和元素类型(int,long等) * TypeName * ArrayTypeName * ClassName * ParameterizedTypeName * TypeVariableName * WildcardTypeName -* CodeBlock -* CodeWriter -* JavaFile -* Util -* NameAllocator +* CodeBlock 用来描述代码块的内容,包括普通的赋值,if判断,循环判断等 +* JavaFile 完整的Java文件 +* CodeWriter 读取JavaFile并转换成Java源文件 ### 使用样例 +通过下面的maven定义可以引用JavaPoet包。 +``` + + com.squareup + javapoet + 1.7.0 + +``` 这里使用JavaPoet定义了一个简单的Java类,完整的代码放在[Github](). ``` java diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java index b7cf16d..7e4145b 100644 --- a/src/main/java/org/wcong/test/poet/JavaFileTest.java +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -27,46 +27,54 @@ public static void main(String[] args) { System.out.println(javaFileBuilder.build().toString()); } - static AnnotationSpec makeAnnotationSpec() { + private static AnnotationSpec makeAnnotationSpec() { AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); builder.addMember("hello", codeBlockBuilder.build()); return builder.build(); } - static FieldSpec makeFieldSpec() { + private static FieldSpec makeFieldSpec() { FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); return fileSpecBuilder.build(); } - static List makeMethodSpec() { + private static List makeMethodSpec() { List methodSpecList = new ArrayList(); + methodSpecList.add(makeGetMethod()); + methodSpecList.add(makeSetMethod()); + methodSpecList.add(makeToStringMethod()); + return methodSpecList; + } - MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); - getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - getMethodSpecBuilder.returns(TypeName.get(String.class)); - getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); - methodSpecList.add(getMethodSpecBuilder.build()); - - MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); - setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - setMethodSpecBuilder.returns(TypeName.VOID); - ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); - setMethodSpecBuilder.addParameter(parameterBuilder.build()); - setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); - methodSpecList.add(setMethodSpecBuilder.build()); - + private static MethodSpec makeToStringMethod() { MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); toStringBuilder.addModifiers(Modifier.PUBLIC); toStringBuilder.returns(TypeName.get(String.class)); CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); toStringCodeBuilder.beginControlFlow("if( hello != null )"); - toStringCodeBuilder.add(CodeBlock.of("return \"hello\"+hello;")); + toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;")); toStringCodeBuilder.endControlFlow(); toStringBuilder.addCode(toStringCodeBuilder.build()); - methodSpecList.add(toStringBuilder.build()); + return toStringBuilder.build(); + } - return methodSpecList; + private static MethodSpec makeSetMethod() { + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + return setMethodSpecBuilder.build(); + } + + private static MethodSpec makeGetMethod() { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + return getMethodSpecBuilder.build(); } } From de9edc8da9fba261ec016b931fe854ca77f4ce4b Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 16 Nov 2016 17:26:13 +0800 Subject: [PATCH 13/96] first finish --- doc/dagger/JavaPoet.md | 111 +++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md index 53af650..e7ebd8e 100644 --- a/doc/dagger/JavaPoet.md +++ b/doc/dagger/JavaPoet.md @@ -36,53 +36,66 @@ Use beautiful Java code to generate beautiful Java code 1.7.0 ``` -这里使用JavaPoet定义了一个简单的Java类,完整的代码放在[Github](). - -``` java - public class JavaFileTest { - public static void main(String[] args) { - TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); - typeSpecBuilder.addAnnotation(makeAnnotationSpec()); - typeSpecBuilder.addField(makeFieldSpec()); - typeSpecBuilder.addMethods(makeMethodSpec()); - JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); - System.out.println(javaFileBuilder.build().toString()); - } - static AnnotationSpec makeAnnotationSpec() { - AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); - CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); - builder.addMember("hello", codeBlockBuilder.build()); - return builder.build(); - } - static FieldSpec makeFieldSpec() { - FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); - fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); - return fileSpecBuilder.build(); - } - static List makeMethodSpec() { - List methodSpecList = new ArrayList(); - MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); - getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - getMethodSpecBuilder.returns(TypeName.get(String.class)); - getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); - methodSpecList.add(getMethodSpecBuilder.build()); - MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); - setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - setMethodSpecBuilder.returns(TypeName.VOID); - ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); - setMethodSpecBuilder.addParameter(parameterBuilder.build()); - setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); - methodSpecList.add(setMethodSpecBuilder.build()); - MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); - toStringBuilder.addModifiers(Modifier.PUBLIC); - toStringBuilder.returns(TypeName.get(String.class)); - CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); - toStringCodeBuilder.beginControlFlow("if( hello != null )"); - toStringCodeBuilder.add(CodeBlock.of("return \"hello\"+hello;")); - toStringCodeBuilder.endControlFlow(); - toStringBuilder.addCode(toStringCodeBuilder.build()); - methodSpecList.add(toStringBuilder.build()); - return methodSpecList; - } +这里使用JavaPoet定义了一个简单的Java类,完整的代码放在[Github](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/poet/JavaFileTest.java)。 +这里介绍一下主要的类。 +1. AnnotationSpec 添加*MyAnnotation*的注解,然后设置属性*hello=world*。 +``` + private static AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); + builder.addMember("hello", codeBlockBuilder.build()); + return builder.build(); } -``` \ No newline at end of file +``` +2. FieldSpec 创建*hello*的字段并初始化为“world”。 +``` + private static FieldSpec makeFieldSpec() { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); + return fileSpecBuilder.build(); + } +``` +3. MethodSpec 创建*getHello*,*setHello*,*toString*方法。 +*toString*使用了*ControlFlow*判断了*hello*不等于null,返回"hello world",等于null的时候返回空。 +``` + private static MethodSpec makeToStringMethod() { + MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); + toStringBuilder.addModifiers(Modifier.PUBLIC); + toStringBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); + toStringCodeBuilder.beginControlFlow("if( hello != null )"); + toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;")); + toStringCodeBuilder.endControlFlow(); + toStringBuilder.addCode(toStringCodeBuilder.build()); + return toStringBuilder.build(); + } + private static MethodSpec makeSetMethod() { + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + return setMethodSpecBuilder.build(); + } + private static MethodSpec makeGetMethod() { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + return getMethodSpecBuilder.build(); + } +``` +4. JavaFile JavaPoet的主入口,用来描述Java源文件。 +``` + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addField(makeFieldSpec()); + typeSpecBuilder.addMethods(makeMethodSpec()); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } +``` +### 结语 +dagger使用JavaPoet来保存自动生成的类的信息,并通过[JavaFormat](https://github.com/google/google-java-format)来格式化生成的Java源文件。后面会介绍关于JavaFormat的内容。 From dbb80dad7e5b18f83559a07d3e4558140801613b Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 17 Nov 2016 10:28:50 +0800 Subject: [PATCH 14/96] save something --- src/main/java/org/wcong/test/poet/JavaFileTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java index 7e4145b..2b5d1d8 100644 --- a/src/main/java/org/wcong/test/poet/JavaFileTest.java +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -54,7 +54,9 @@ private static MethodSpec makeToStringMethod() { toStringBuilder.returns(TypeName.get(String.class)); CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); toStringCodeBuilder.beginControlFlow("if( hello != null )"); - toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;")); + toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;\n")); + toStringCodeBuilder.nextControlFlow("else"); + toStringCodeBuilder.add(CodeBlock.of("return \"\";\n")); toStringCodeBuilder.endControlFlow(); toStringBuilder.addCode(toStringCodeBuilder.build()); return toStringBuilder.build(); @@ -66,7 +68,7 @@ private static MethodSpec makeSetMethod() { setMethodSpecBuilder.returns(TypeName.VOID); ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); setMethodSpecBuilder.addParameter(parameterBuilder.build()); - setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;\n").build()); return setMethodSpecBuilder.build(); } @@ -74,7 +76,7 @@ private static MethodSpec makeGetMethod() { MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); getMethodSpecBuilder.returns(TypeName.get(String.class)); - getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;\n").build()); return getMethodSpecBuilder.build(); } } From 19dc41e5758e75db6db4bc0021a080bb9319cc13 Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 17 Nov 2016 16:19:06 +0800 Subject: [PATCH 15/96] add format class --- pom.xml | 2 +- .../org/wcong/test/javaformat/FormatTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/wcong/test/javaformat/FormatTest.java diff --git a/pom.xml b/pom.xml index 1f35b15..f81cbc5 100644 --- a/pom.xml +++ b/pom.xml @@ -310,7 +310,7 @@ com.google.googlejavaformat google-java-format - 1.1 + 1.0 diff --git a/src/main/java/org/wcong/test/javaformat/FormatTest.java b/src/main/java/org/wcong/test/javaformat/FormatTest.java new file mode 100644 index 0000000..becc00f --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/FormatTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.javaformat; + +import com.google.googlejavaformat.java.Main; + +/** + * Created by wcong on 2016/11/17. + */ +public class FormatTest { + + public static void main(String[] args) { + String[] files = new String[1]; + files[0] = "src/main/java/org/wcong/test/guice/GuiceTest.java"; + Main.main(files); + } +} From f92abd50235af687d6df64d5f503547f218ea1fa Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 21 Nov 2016 15:11:38 +0800 Subject: [PATCH 16/96] add IScanner --- pom.xml | 5 +++ .../wcong/test/javaformat/IScannerTest.java | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/org/wcong/test/javaformat/IScannerTest.java diff --git a/pom.xml b/pom.xml index f81cbc5..439effc 100644 --- a/pom.xml +++ b/pom.xml @@ -312,6 +312,11 @@ google-java-format 1.0 + + org.eclipse.jdt + org.eclipse.jdt.core + 3.10.0 + diff --git a/src/main/java/org/wcong/test/javaformat/IScannerTest.java b/src/main/java/org/wcong/test/javaformat/IScannerTest.java new file mode 100644 index 0000000..9082e93 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/IScannerTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.javaformat; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.compiler.IScanner; +import org.eclipse.jdt.core.compiler.InvalidInputException; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * test for IScanner + * Created by wcong on 2016/11/21. + */ +public class IScannerTest { + public static void main(String[] args) throws IOException, InvalidInputException { + IScanner scanner = ToolFactory.createScanner(true, true, true, "1.8"); + Path path = Paths.get("src/main/java/org/wcong/test/guice/GuiceTest.java"); + String text = new String(Files.readAllBytes(path)); + int textLength = text.length(); + scanner.setSource(text.toCharArray()); + while (scanner.getCurrentTokenEndPosition() < textLength - 1) { + scanner.getNextToken(); + int charI0 = scanner.getCurrentTokenStartPosition(); + // Get string, possibly with Unicode escapes. + String originalTokText = text.substring(charI0, scanner.getCurrentTokenEndPosition() + 1); + System.out.println(originalTokText); + } + } +} From 04809903e08abd1308e9437fdf999cbbdd472e6c Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 21 Nov 2016 15:30:14 +0800 Subject: [PATCH 17/96] add ASTParser --- .../wcong/test/javaformat/ASTParserTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/org/wcong/test/javaformat/ASTParserTest.java diff --git a/src/main/java/org/wcong/test/javaformat/ASTParserTest.java b/src/main/java/org/wcong/test/javaformat/ASTParserTest.java new file mode 100644 index 0000000..1fa0cc3 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/ASTParserTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.javaformat; + +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Created by wcong on 2016/11/21. + */ +public class ASTParserTest { + public static void main(String[] args) throws IOException { + ASTParser parser = ASTParser.newParser(AST.JLS8); + Path path = Paths.get("src/main/java/org/wcong/test/guice/GuiceTest.java"); + String text = new String(Files.readAllBytes(path)); + parser.setSource(text.toCharArray()); + CompilationUnit unit = (CompilationUnit) parser.createAST(null); + unit.getJavaElement(); + } +} From da173d380c4e006867bb755690fedae19f091bc0 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 21 Nov 2016 17:30:52 +0800 Subject: [PATCH 18/96] add range --- .../java/org/wcong/test/javaformat/RangeTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/org/wcong/test/javaformat/RangeTest.java diff --git a/src/main/java/org/wcong/test/javaformat/RangeTest.java b/src/main/java/org/wcong/test/javaformat/RangeTest.java new file mode 100644 index 0000000..331f568 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/RangeTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.javaformat; + +import com.google.common.collect.Range; + +/** + * Created by wcong on 2016/11/21. + */ +public class RangeTest { + + public static void main(String[] args) { + Range stringRange = Range.open("a", "b"); + System.out.println(stringRange); + System.out.println(stringRange.span(Range.open("c", "d"))); + } +} From f56bc3f56fdd61b319ff0b1b3f3a1506833a772b Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 22 Nov 2016 15:51:35 +0800 Subject: [PATCH 19/96] auto value --- pom.xml | 10 +++++----- .../test/autovalue/AutoAnnotationTest.java | 19 +++++++++++++++++++ .../wcong/test/autovalue/AutoValueTest.java | 11 +++++++++++ .../wcong/test/autovalue/MyAnnotation.java | 15 +++++++++++++++ .../test/autovalue/MyAnnotationImpl.java | 16 ++++++++++++++++ .../org/wcong/test/autovalue/MyClass.java | 15 +++++++++++++++ 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java create mode 100644 src/main/java/org/wcong/test/autovalue/AutoValueTest.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyAnnotation.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyClass.java diff --git a/pom.xml b/pom.xml index 439effc..db25ad4 100644 --- a/pom.xml +++ b/pom.xml @@ -297,11 +297,11 @@ auto-service 1.0-rc2 - - - - - + + com.google.auto.value + auto-value + 1.3 + com.squareup javapoet diff --git a/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java b/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java new file mode 100644 index 0000000..9eedd6d --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java @@ -0,0 +1,19 @@ +package org.wcong.test.autovalue; + +import com.google.auto.value.AutoAnnotation; + +/** + * Created by hzwangcong on 2016/11/22. + */ +public class AutoAnnotationTest { + + public static void main(String[] args) { + MyAnnotation myAnnotation = new MyAnnotationImpl(); + System.out.println(myAnnotation("hello")); + } + + @AutoAnnotation + public static MyAnnotation myAnnotation(String value) { + return new AutoAnnotation_AutoAnnotationTest_myAnnotation(value); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/AutoValueTest.java b/src/main/java/org/wcong/test/autovalue/AutoValueTest.java new file mode 100644 index 0000000..bfc34bb --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/AutoValueTest.java @@ -0,0 +1,11 @@ +package org.wcong.test.autovalue; + +/** + * Created by wcong on 2016/11/22. + */ +public class AutoValueTest { + public static void main(String[] args) { + MyClass myClass = MyClass.create("world"); + System.out.println(myClass); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAnnotation.java b/src/main/java/org/wcong/test/autovalue/MyAnnotation.java new file mode 100644 index 0000000..084d22f --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAnnotation.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by hzwangcong on 2016/11/22. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface MyAnnotation { + String value(); +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java b/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java new file mode 100644 index 0000000..4e627bf --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java @@ -0,0 +1,16 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.Annotation; + +/** + * Created by hzwangcong on 2016/11/22. + */ +public class MyAnnotationImpl implements MyAnnotation { + public String value() { + return null; + } + + public Class annotationType() { + return null; + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyClass.java b/src/main/java/org/wcong/test/autovalue/MyClass.java new file mode 100644 index 0000000..679a493 --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyClass.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import com.google.auto.value.AutoValue; + +/** + * Created by wcong on 2016/11/22. + */ +@AutoValue +abstract class MyClass { + static MyClass create(String hello) { + return new AutoValue_MyClass(hello); + } + + abstract String hello(); +} From 007fb6da5189cbfa69427b36d245291b2a4fd948 Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 26 Nov 2016 17:33:50 +0800 Subject: [PATCH 20/96] still for annotation --- doc/dagger/AutoValue.md | 0 .../org/wcong/test/autovalue/MyAutoValue.java | 8 + .../test/autovalue/MyAutoValueClassTest.java | 13 ++ .../test/autovalue/MyAutoValueProcesser.java | 161 ++++++++++++++++++ .../wcong/test/autovalue/MyAutoValueTest.java | 10 ++ .../javax.annotation.processing.Processor | 0 6 files changed, 192 insertions(+) create mode 100644 doc/dagger/AutoValue.md create mode 100644 src/main/java/org/wcong/test/autovalue/MyAutoValue.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java create mode 100644 src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java create mode 100644 src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/doc/dagger/AutoValue.md b/doc/dagger/AutoValue.md new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValue.java b/src/main/java/org/wcong/test/autovalue/MyAutoValue.java new file mode 100644 index 0000000..ce4614c --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValue.java @@ -0,0 +1,8 @@ +package org.wcong.test.autovalue; + +/** + * my auto value + * Created by wcong on 2016/11/25. + */ +public @interface MyAutoValue { +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java new file mode 100644 index 0000000..f37547f --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java @@ -0,0 +1,13 @@ +package org.wcong.test.autovalue; + +/** + * Created by hzwangcong on 2016/11/25. + */ +@MyAutoValue +public class MyAutoValueClassTest { + + private String a; + + private String b; + +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java new file mode 100644 index 0000000..ba9ced3 --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java @@ -0,0 +1,161 @@ +package org.wcong.test.autovalue; + +import com.google.auto.service.AutoService; +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import javax.annotation.Generated; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Type; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * process for MyAutoValue + * Created by wcong on 2016/11/25. + */ +@AutoService(Processor.class) +public class MyAutoValueProcesser extends AbstractProcessor { + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + @Override + public Set getSupportedAnnotationTypes() { + Set annotationTypes = new HashSet<>(); + annotationTypes.add(MyAutoValue.class.toString()); + return annotationTypes; + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Set elements = roundEnv.getElementsAnnotatedWith(MyAutoValue.class); + if (elements == null || elements.isEmpty()) { + return false; + } +// for (Element element : elements) { +// if (!(element instanceof TypeElement)) { +// continue; +// } +// try { +// processType(element); +// } catch (Exception e) { +// processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); +// } +// } + return false; + } + + private void processType(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = element.getSimpleName() + "_MyAutoValue"; + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + String packageName = getPackageName(typeElement); + try { + makeFields(typeElement, typeSpecBuilder); + } catch (ClassNotFoundException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + try { + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } + + private String getPackageName(Element typeElement) { + while (true) { + Element enclosingElement = typeElement.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + typeElement = enclosingElement; + } + } + + private void makeFields(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { + List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); + if (elementList == null || elementList.isEmpty()) { + return; + } + for (VariableElement variableElement : elementList) { + String fieldName = variableElement.getSimpleName().toString(); + Type type = Class.forName(variableElement.asType().toString()); + typeSpecBuilder.addField(makeFieldSpec(fieldName, type)); + typeSpecBuilder.addMethod(makeSetMethod(fieldName, type)); + typeSpecBuilder.addMethod(makeGetMethod(fieldName, type)); + } + } + + private AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(Generated.class); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "MyAutoValue"); + builder.addMember("value", codeBlockBuilder.build()); + return builder.build(); + } + + private static FieldSpec makeFieldSpec(String fieldName, Type type) { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(type, fieldName, Modifier.PRIVATE); + return fileSpecBuilder.build(); + } + + private MethodSpec makeSetMethod(String fieldName, Type type) { + String upperFieldName = getUpperString(fieldName); + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("set" + upperFieldName); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(type, fieldName); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this." + fieldName + " = " + fieldName + ";\n").build()); + return setMethodSpecBuilder.build(); + } + + private String getUpperString(String fieldName) { + if (fieldName.length() == 1) { + fieldName = fieldName.toUpperCase(); + } else { + fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + } + return fieldName; + } + + private MethodSpec makeGetMethod(String fieldName, Type type) { + String upperFieldName = getUpperString(fieldName); + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get" + upperFieldName); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(type); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return " + fieldName + ";\n").build()); + return getMethodSpecBuilder.build(); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java new file mode 100644 index 0000000..8346b6e --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java @@ -0,0 +1,10 @@ +package org.wcong.test.autovalue; + +/** + * Created by wcong on 2016/11/26. + */ +public class MyAutoValueTest { + public static void main(String[] args) { + + } +} diff --git a/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..e69de29 From b8d0ed68b3d8888b6bb7273992552a197fbe2ccc Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 28 Nov 2016 16:46:29 +0800 Subject: [PATCH 21/96] add build --- pom.xml | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index db25ad4..68d4f83 100644 --- a/pom.xml +++ b/pom.xml @@ -218,34 +218,34 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -319,4 +319,20 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + false + false + + + + From dfb3fe537e6cbe5b92c79d6365e7bb9443bf70bd Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 28 Nov 2016 16:47:48 +0800 Subject: [PATCH 22/96] save --- .../annotation/AnnotationProcessorTest.java | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java diff --git a/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java b/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java deleted file mode 100644 index 6723831..0000000 --- a/src/main/java/org/wcong/test/dagger/annotation/AnnotationProcessorTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.wcong.test.dagger.annotation; - -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.util.TreePath; -import com.sun.source.util.TreePathScanner; -import com.sun.source.util.Trees; -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeTranslator; - -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.tools.JavaFileObject; -import java.util.Set; - -/** - * @author wcong - * @since 2016/11/4 - */ -public class AnnotationProcessorTest { - public static void main(String[] args) { - - } - - @SupportedAnnotationTypes("org.wcong.test.dagger.annotation.MyAnnotation") - static class MyProcessor extends AbstractProcessor { - - private Trees trees; - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - trees = Trees.instance(processingEnv); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - - final TreePathScanner scanner = new TreePathScanner() { - public Trees visitClass(final ClassTree classTree, final CompilationUnitTree unitTree) { - if (unitTree instanceof JCTree.JCCompilationUnit) { - final JCTree.JCCompilationUnit compilationUnit = (JCTree.JCCompilationUnit) unitTree; - if (compilationUnit.sourcefile.getKind() == JavaFileObject.Kind.SOURCE) { - compilationUnit.accept(new TreeTranslator() { - public void visitVarDef(final JCTree.JCVariableDecl tree) { - super.visitVarDef(tree); - if ((tree.mods.flags & Flags.FINAL) == 0) { - tree.mods.flags |= Flags.FINAL; - - } - } - public void visitClassDef(JCTree.JCClassDecl tree) { - super.visitClassDef(tree); - //tree.implementing = tree.implementing.add(new JCTree.JCClassDecl()); - } - }); - } - - } - return trees; - - } - }; - Set elements = roundEnv.getElementsAnnotatedWith(MyAnnotation.class); - for (Element element : elements) { - final TreePath path = trees.getPath(element); - scanner.scan(path, path.getCompilationUnit()); - } - return true; - } - } - - @MyAnnotation - static class ParseClass { - - } -} From 7368af146cc9441c282fb57bc6eae19541739f26 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 28 Nov 2016 19:45:13 +0800 Subject: [PATCH 23/96] finally annotation processor --- annotation/pom.xml | 40 +++++++++++++++++++ .../org/wcong/test/autovalue/MyAutoValue.java | 15 +++++++ .../test/autovalue/MyAutoValueProcessor.java | 25 ++++++------ pom.xml | 9 ++++- .../org/wcong/test/autovalue/MyAutoValue.java | 8 ---- .../javax.annotation.processing.Processor | 0 6 files changed, 75 insertions(+), 22 deletions(-) create mode 100644 annotation/pom.xml create mode 100644 annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java rename src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java => annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java (91%) delete mode 100644 src/main/java/org/wcong/test/autovalue/MyAutoValue.java delete mode 100644 src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/annotation/pom.xml b/annotation/pom.xml new file mode 100644 index 0000000..47185eb --- /dev/null +++ b/annotation/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + org.wcong + learn-java-annotation + 1.0-SNAPSHOT + jar + + learn-java-annotation + http://maven.apache.org + + + + com.squareup + javapoet + 1.7.0 + + + com.google.auto.service + auto-service + 1.0-rc2 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + + + + + \ No newline at end of file diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java new file mode 100644 index 0000000..fd90751 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * my auto value + * Created by wcong on 2016/11/25. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyAutoValue { +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java similarity index 91% rename from src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java rename to annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java index ba9ced3..155b801 100644 --- a/src/main/java/org/wcong/test/autovalue/MyAutoValueProcesser.java +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java @@ -35,7 +35,7 @@ * Created by wcong on 2016/11/25. */ @AutoService(Processor.class) -public class MyAutoValueProcesser extends AbstractProcessor { +public class MyAutoValueProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { @@ -45,7 +45,7 @@ public SourceVersion getSupportedSourceVersion() { @Override public Set getSupportedAnnotationTypes() { Set annotationTypes = new HashSet<>(); - annotationTypes.add(MyAutoValue.class.toString()); + annotationTypes.add(MyAutoValue.class.getName()); return annotationTypes; } @@ -55,16 +55,17 @@ public boolean process(Set annotations, RoundEnvironment if (elements == null || elements.isEmpty()) { return false; } -// for (Element element : elements) { -// if (!(element instanceof TypeElement)) { -// continue; -// } -// try { -// processType(element); -// } catch (Exception e) { -// processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); -// } -// } + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,elements.toString()); + for (Element element : elements) { + if (!(element instanceof TypeElement)) { + continue; + } + try { + processType(element); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } return false; } diff --git a/pom.xml b/pom.xml index 68d4f83..b4466ad 100644 --- a/pom.xml +++ b/pom.xml @@ -3,11 +3,11 @@ 4.0.0 org.wcong - learn-spring + learn-java 1.0-SNAPSHOT jar - learn-spring + learn-java http://maven.apache.org @@ -317,6 +317,11 @@ org.eclipse.jdt.core 3.10.0 + + org.wcong + learn-java-annotation + 1.0-SNAPSHOT + diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValue.java b/src/main/java/org/wcong/test/autovalue/MyAutoValue.java deleted file mode 100644 index ce4614c..0000000 --- a/src/main/java/org/wcong/test/autovalue/MyAutoValue.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.wcong.test.autovalue; - -/** - * my auto value - * Created by wcong on 2016/11/25. - */ -public @interface MyAutoValue { -} diff --git a/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index e69de29..0000000 From 1034172af88d306fc74abd4f3b7e2a125418ffe5 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 28 Nov 2016 19:54:14 +0800 Subject: [PATCH 24/96] finally annotation processor --- annotation/pom.xml | 6 +----- .../java/org/wcong/test/autovalue/MyAutoValueProcessor.java | 4 ---- .../META-INF/services/javax.annotation.processing.Processor | 1 + 3 files changed, 2 insertions(+), 9 deletions(-) create mode 100644 annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/annotation/pom.xml b/annotation/pom.xml index 47185eb..a35e687 100644 --- a/annotation/pom.xml +++ b/annotation/pom.xml @@ -16,11 +16,6 @@ javapoet 1.7.0 - - com.google.auto.service - auto-service - 1.0-rc2 - @@ -33,6 +28,7 @@ 1.7 1.7 UTF-8 + -proc:none diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java index 155b801..40e3d2f 100644 --- a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java @@ -1,6 +1,5 @@ package org.wcong.test.autovalue; -import com.google.auto.service.AutoService; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; @@ -12,7 +11,6 @@ import javax.annotation.Generated; import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; @@ -34,7 +32,6 @@ * process for MyAutoValue * Created by wcong on 2016/11/25. */ -@AutoService(Processor.class) public class MyAutoValueProcessor extends AbstractProcessor { @Override @@ -55,7 +52,6 @@ public boolean process(Set annotations, RoundEnvironment if (elements == null || elements.isEmpty()) { return false; } - processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,elements.toString()); for (Element element : elements) { if (!(element instanceof TypeElement)) { continue; diff --git a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..e88cbd1 --- /dev/null +++ b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +org.wcong.test.autovalue.MyAutoValueProcessor \ No newline at end of file From 1afcac0d16d5d5a9c4869677380d0802691a50c6 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 29 Nov 2016 14:12:46 +0800 Subject: [PATCH 25/96] optimize --- .../test/autovalue/MyAutoValueProcessor.java | 50 ++++++++++++++----- .../test/autovalue/MyAutoValueClassTest.java | 2 + .../wcong/test/autovalue/MyAutoValueTest.java | 6 ++- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java index 40e3d2f..564835e 100644 --- a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java @@ -23,7 +23,7 @@ import javax.tools.JavaFileObject; import java.io.IOException; import java.io.Writer; -import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -59,7 +59,7 @@ public boolean process(Set annotations, RoundEnvironment try { processType(element); } catch (Exception e) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); } } return false; @@ -70,6 +70,7 @@ private void processType(Element element) { String className = element.getSimpleName() + "_MyAutoValue"; TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); String packageName = getPackageName(typeElement); try { makeFields(typeElement, typeSpecBuilder); @@ -106,13 +107,38 @@ private void makeFields(Element element, TypeSpec.Builder typeSpecBuilder) throw if (elementList == null || elementList.isEmpty()) { return; } + List fieldList = new ArrayList<>(elementList.size()); for (VariableElement variableElement : elementList) { String fieldName = variableElement.getSimpleName().toString(); - Type type = Class.forName(variableElement.asType().toString()); - typeSpecBuilder.addField(makeFieldSpec(fieldName, type)); - typeSpecBuilder.addMethod(makeSetMethod(fieldName, type)); - typeSpecBuilder.addMethod(makeGetMethod(fieldName, type)); + fieldList.add(fieldName); + TypeName typeName = TypeName.get(variableElement.asType()); + typeSpecBuilder.addField(makeFieldSpec(fieldName, typeName)); + typeSpecBuilder.addMethod(makeSetMethod(fieldName, typeName)); + typeSpecBuilder.addMethod(makeGetMethod(fieldName, typeName)); } + typeSpecBuilder.addMethod(makeToStringMethod(fieldList)); + } + + private MethodSpec makeToStringMethod(List fieldList) { + MethodSpec.Builder toStringMethodSpecBuilder = MethodSpec.methodBuilder("toString"); + toStringMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + toStringMethodSpecBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder codeBuilder = CodeBlock.builder(); + if (fieldList != null && !fieldList.isEmpty()) { + StringBuilder toStringBuilder = new StringBuilder(fieldList.size() * 10); + for (String field : fieldList) { + if (toStringBuilder.length() > 0) { + toStringBuilder.append(","); + } + toStringBuilder.append("\\\"").append(field).append("\\\"") + .append(":\\\"\"+").append(field).append("+\"\\\""); + } + codeBuilder.add("return \"{" + toStringBuilder.toString() + "}\";"); + } else { + codeBuilder.add("return \"{}\";"); + } + toStringMethodSpecBuilder.addCode(codeBuilder.build()); + return toStringMethodSpecBuilder.build(); } private AnnotationSpec makeAnnotationSpec() { @@ -122,17 +148,17 @@ private AnnotationSpec makeAnnotationSpec() { return builder.build(); } - private static FieldSpec makeFieldSpec(String fieldName, Type type) { - FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(type, fieldName, Modifier.PRIVATE); + private static FieldSpec makeFieldSpec(String fieldName, TypeName typeName) { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(typeName, fieldName, Modifier.PRIVATE); return fileSpecBuilder.build(); } - private MethodSpec makeSetMethod(String fieldName, Type type) { + private MethodSpec makeSetMethod(String fieldName, TypeName typeName) { String upperFieldName = getUpperString(fieldName); MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("set" + upperFieldName); setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); setMethodSpecBuilder.returns(TypeName.VOID); - ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(type, fieldName); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(typeName, fieldName); setMethodSpecBuilder.addParameter(parameterBuilder.build()); setMethodSpecBuilder.addCode(CodeBlock.builder().add("this." + fieldName + " = " + fieldName + ";\n").build()); return setMethodSpecBuilder.build(); @@ -147,11 +173,11 @@ private String getUpperString(String fieldName) { return fieldName; } - private MethodSpec makeGetMethod(String fieldName, Type type) { + private MethodSpec makeGetMethod(String fieldName, TypeName typeName) { String upperFieldName = getUpperString(fieldName); MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get" + upperFieldName); getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - getMethodSpecBuilder.returns(type); + getMethodSpecBuilder.returns(typeName); getMethodSpecBuilder.addCode(CodeBlock.builder().add("return " + fieldName + ";\n").build()); return getMethodSpecBuilder.build(); } diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java index f37547f..318a24b 100644 --- a/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java @@ -10,4 +10,6 @@ public class MyAutoValueClassTest { private String b; + private int c; + } diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java index 8346b6e..da02751 100644 --- a/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java @@ -5,6 +5,10 @@ */ public class MyAutoValueTest { public static void main(String[] args) { - + org.wcong.test.autovalue.MyAutoValueClassTest_MyAutoValue myAutoValueClassTest_myAutoValue = new org.wcong.test.autovalue.MyAutoValueClassTest_MyAutoValue(); + myAutoValueClassTest_myAutoValue.setA("a"); + myAutoValueClassTest_myAutoValue.setB("b"); + myAutoValueClassTest_myAutoValue.setC(1); + System.out.println(myAutoValueClassTest_myAutoValue.toString()); } } From e68cdd5513b632d861df4306a76db8c3fc55389e Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 29 Nov 2016 17:17:02 +0800 Subject: [PATCH 26/96] save autovalue md --- .../test/autovalue/MyAutoValueProcessor.java | 8 +- doc/dagger/AutoValue.md | 193 ++++++++++++++++++ 2 files changed, 197 insertions(+), 4 deletions(-) diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java index 564835e..9dfccd8 100644 --- a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java @@ -50,7 +50,7 @@ public Set getSupportedAnnotationTypes() { public boolean process(Set annotations, RoundEnvironment roundEnv) { Set elements = roundEnv.getElementsAnnotatedWith(MyAutoValue.class); if (elements == null || elements.isEmpty()) { - return false; + return true; } for (Element element : elements) { if (!(element instanceof TypeElement)) { @@ -62,7 +62,7 @@ public boolean process(Set annotations, RoundEnvironment processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); } } - return false; + return true; } private void processType(Element element) { @@ -73,7 +73,7 @@ private void processType(Element element) { typeSpecBuilder.addModifiers(Modifier.PUBLIC); String packageName = getPackageName(typeElement); try { - makeFields(typeElement, typeSpecBuilder); + makeFieldAndMethod(typeElement, typeSpecBuilder); } catch (ClassNotFoundException e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); } @@ -102,7 +102,7 @@ private String getPackageName(Element typeElement) { } } - private void makeFields(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { + private void makeFieldAndMethod(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); if (elementList == null || elementList.isEmpty()) { return; diff --git a/doc/dagger/AutoValue.md b/doc/dagger/AutoValue.md index e69de29..336f356 100644 --- a/doc/dagger/AutoValue.md +++ b/doc/dagger/AutoValue.md @@ -0,0 +1,193 @@ +### 前言 +[上一篇文章](./76e9e3a8ec0f)介绍了JavaPoet的使用,这里在介绍一下[AutoValue](https://github.com/google/auto)的使用。 +AutoValue的是Google为了实现*ValueClass*设计的自动编译框架,具体的介绍可以参考Google的官方[解释](https://github.com/google/auto/blob/master/value/userguide/index.md)。 +### AutoValue +AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建一个新的ValueClass。具体的使用可以参考[例子](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/AutoValueTest.java)。 +这里主要介绍一下AutoValue的实现。 +1. 定义注解AutoValue +``` + @Retention(RetentionPolicy.SOURCE) + @Target(ElementType.TYPE) + public @interface AutoValue { + } +``` +2. 注册*processor*,AutoValue的jar包中的*META-INF/services*路径里面包含文件*javax.annotation.processing.Processor*,文件里包含了注册的processor,换行分割。这里面注册了*AutoValueProcessor*。 +3. *AutoValueProcessor*的*process*方法实现l额主要的业务逻辑,读取注释的类的信息,构造新的类,并写入文件。 +``` + AutoValueTemplateVars vars = new AutoValueTemplateVars(); + vars.pkg = TypeSimplifier.packageNameOf(type); + vars.origClass = TypeSimplifier.classNameOf(type); + vars.simpleClassName = TypeSimplifier.simpleNameOf(vars.origClass); + vars.subclass = TypeSimplifier.simpleNameOf(subclass); + vars.finalSubclass = TypeSimplifier.simpleNameOf(finalSubclass); + vars.isFinal = applicableExtensions.isEmpty(); + vars.types = processingEnv.getTypeUtils(); + determineObjectMethodsToGenerate(methods, vars); + defineVarsForType(type, vars, toBuilderMethods, propertyMethods, builder); + GwtCompatibility gwtCompatibility = new GwtCompatibility(type); + vars.gwtCompatibleAnnotation = gwtCompatibility.gwtCompatibleAnnotationString(); + String text = vars.toText(); + text = Reformatter.fixup(text); + writeSourceFile(subclass, text, type); +``` +*AutoValueTemplateVars*保存了新的类的信息,并根据对应的模板生成源文件字符串. +``` + private void writeSourceFile(String className, String text, TypeElement originatingType) { + try { + JavaFileObject sourceFile = + processingEnv.getFiler().createSourceFile(className, originatingType); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, + "Could not write generated class " + className + ": " + e); + } + } +``` +*writeSourceFile*则会根据原生api将源代码写入本地文件。 + +### MyAutoValue +所以自定义*AutoValue*也是类似的原理。因为*processor*的注册不能在jar中使用,不能跟源文件放在一起,所以这里新建了一个[工程](https://github.com/wcong/learn-java/tree/master/annotation)来实现*MyAutoValue*,使用方法在[这里](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java)。 +1. 定义*MyAutoValue*。 +``` +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyAutoValue { +} +``` +2. *MyAutoValueProcessor*。同样先在*resources/META-INF/services*下新建*javax.annotation.processing.Processor*,并注册*MyAutoValueProcessor*。 +*MyAutoValueProcessor*继承了*AbstractProcessor*,并在*process*中实现了主要的逻辑。 +``` + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Set elements = roundEnv.getElementsAnnotatedWith(MyAutoValue.class); + if (elements == null || elements.isEmpty()) { + return true; + } + for (Element element : elements) { + if (!(element instanceof TypeElement)) { + continue; + } + try { + processType(element); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); + } + } + return true; + } +``` +这里去取了所有被*MyAutoValue*注释的类,并交给processType去处理 +``` + private void processType(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = element.getSimpleName() + "_MyAutoValue"; + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + String packageName = getPackageName(typeElement); + try { + makeFieldAndMethod(typeElement, typeSpecBuilder); + } catch (ClassNotFoundException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + try { + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } +``` +*processType*会读取类的字段,并根据这些字段生成get,set和toString方法,然后写入到本地文件中。 +``` + private void makeFieldAndMethod(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { + List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); + if (elementList == null || elementList.isEmpty()) { + return; + } + List fieldList = new ArrayList<>(elementList.size()); + for (VariableElement variableElement : elementList) { + String fieldName = variableElement.getSimpleName().toString(); + fieldList.add(fieldName); + TypeName typeName = TypeName.get(variableElement.asType()); + typeSpecBuilder.addField(makeFieldSpec(fieldName, typeName)); + typeSpecBuilder.addMethod(makeSetMethod(fieldName, typeName)); + typeSpecBuilder.addMethod(makeGetMethod(fieldName, typeName)); + } + typeSpecBuilder.addMethod(makeToStringMethod(fieldList)); + } +``` +*makeFieldAndMethod*就是具体的构造字段和方法的逻辑,内部使用JavaPoet实现的,可以参考完整代码和上一篇文章,这里就不列出了。 +3. 打包编译,需要注意的*META-INF/services*的*javax.annotation.processing.Processor*会阻止javac的编译,打完包会发现里面没有class文件,所以需要加上特殊的参数。 +``` + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + -proc:none + + + + +``` +加上*-proc:none*就可以实现完整的打包了。 +4. 使用*MyAutoValue*。在*MyAutoValueClassTest*类上注解*MyAutoValue*。编译 +``` + @MyAutoValue + public class MyAutoValueClassTest { + private String a; + private String b; + private int c; + } +``` +编译完后就会生成一下的类。 +``` +public class MyAutoValueClassTest_MyAutoValue { + private String a; + private String b; + private int c; + public MyAutoValueClassTest_MyAutoValue() { + } + public void setA(String a) { + this.a = a; + } + public String getA() { + return this.a; + } + public void setB(String b) { + this.b = b; + } + public String getB() { + return this.b; + } + public void setC(int c) { + this.c = c; + } + public int getC() { + return this.c; + } + public String toString() { + return "{\"a\":\"" + this.a + "\",\"b\":\"" + this.b + "\",\"c\":\"" + this.c + "\"}"; + } +} +``` +### 结语 +dagger的实现跟AutoValue类似,也是根据注解嵌入编译实现新的类,只是AutoValue的逻辑比较简单,只是实现ValueClass的构造,dagger会涉及到更多依赖注入的功能,dagger也依赖了AutoValue来实现了很多功能。后面会介绍更多dagger的内容。 \ No newline at end of file From 0fbae1feb9db53508da9a1b0b0c82d5c5329f898 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 30 Nov 2016 10:36:56 +0800 Subject: [PATCH 27/96] optimize --- doc/dagger/AutoValue.md | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/doc/dagger/AutoValue.md b/doc/dagger/AutoValue.md index 336f356..0bdb602 100644 --- a/doc/dagger/AutoValue.md +++ b/doc/dagger/AutoValue.md @@ -1,18 +1,19 @@ ### 前言 -[上一篇文章](./76e9e3a8ec0f)介绍了JavaPoet的使用,这里在介绍一下[AutoValue](https://github.com/google/auto)的使用。 -AutoValue的是Google为了实现*ValueClass*设计的自动编译框架,具体的介绍可以参考Google的官方[解释](https://github.com/google/auto/blob/master/value/userguide/index.md)。 +[上一篇文章](./76e9e3a8ec0f)介绍了JavaPoet的使用,这里在介绍一下[AutoValue](https://github.com/google/auto)的原理,并模仿自定义实现一个AutoValue。 +AutoValue的是Google为了实现*ValueClass*设计的自动编译框架,具体的介绍可以参考Google的官方[说明](https://github.com/google/auto/blob/master/value/userguide/index.md)。 +Dagger内部也大量使用了AutoValue的功能,来实现*ValueClass*。 ### AutoValue -AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建一个新的ValueClass。具体的使用可以参考[例子](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/AutoValueTest.java)。 +AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建一个新的ValueClass。这里有一个完整使用的[例子](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/AutoValueTest.java)。 这里主要介绍一下AutoValue的实现。 -1. 定义注解AutoValue +1. 定义注解*AutoValue*。 ``` @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface AutoValue { } ``` -2. 注册*processor*,AutoValue的jar包中的*META-INF/services*路径里面包含文件*javax.annotation.processing.Processor*,文件里包含了注册的processor,换行分割。这里面注册了*AutoValueProcessor*。 -3. *AutoValueProcessor*的*process*方法实现l额主要的业务逻辑,读取注释的类的信息,构造新的类,并写入文件。 +2. 注册*processor*,AutoValue的jar包中的*META-INF/services*路径里面包含文件*javax.annotation.processing.Processor*,文件里包含了注册的*processor*,换行分割。这里面注册了*AutoValueProcessor*。 +3. *AutoValueProcessor*的*process*方法实现了主要的处理逻辑,读取注释的类的信息,构造新的类,并写入文件。 ``` AutoValueTemplateVars vars = new AutoValueTemplateVars(); vars.pkg = TypeSimplifier.packageNameOf(type); @@ -33,25 +34,26 @@ AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建 *AutoValueTemplateVars*保存了新的类的信息,并根据对应的模板生成源文件字符串. ``` private void writeSourceFile(String className, String text, TypeElement originatingType) { - try { - JavaFileObject sourceFile = - processingEnv.getFiler().createSourceFile(className, originatingType); - Writer writer = sourceFile.openWriter(); - try { - writer.write(text); - } finally { - writer.close(); - } - } catch (IOException e) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, - "Could not write generated class " + className + ": " + e); + try { + JavaFileObject sourceFile = + processingEnv.getFiler().createSourceFile(className, originatingType); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, + "Could not write generated class " + className + ": " + e); + } } - } ``` *writeSourceFile*则会根据原生api将源代码写入本地文件。 ### MyAutoValue -所以自定义*AutoValue*也是类似的原理。因为*processor*的注册不能在jar中使用,不能跟源文件放在一起,所以这里新建了一个[工程](https://github.com/wcong/learn-java/tree/master/annotation)来实现*MyAutoValue*,使用方法在[这里](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java)。 +所以自定义*AutoValue*也是类似的原理。这里构造*MyAutoValue*来读取注解的类,生成新的带有get,set和toString方法类。 +因为*processor*的注册只能在jar中使用,不能跟源文件放在一起,所以这里新建了一个[工程](https://github.com/wcong/learn-java/tree/master/annotation)来实现*MyAutoValue*,使用方法在[这里](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java)。 1. 定义*MyAutoValue*。 ``` @Retention(RetentionPolicy.SOURCE) @@ -81,7 +83,7 @@ public @interface MyAutoValue { return true; } ``` -这里去取了所有被*MyAutoValue*注释的类,并交给processType去处理 +这里去取了所有被*MyAutoValue*注释的类,并交给processType去处理。 ``` private void processType(Element element) { TypeElement typeElement = (TypeElement) element; @@ -110,7 +112,7 @@ public @interface MyAutoValue { } } ``` -*processType*会读取类的字段,并根据这些字段生成get,set和toString方法,然后写入到本地文件中。 +*processType*会读取类的字段生成一个新的*_MyAutoValue的类,并根据原有类的字段生成get,set和toString方法,然后将新类写入到本地文件中。 ``` private void makeFieldAndMethod(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); @@ -149,7 +151,7 @@ public @interface MyAutoValue { ``` 加上*-proc:none*就可以实现完整的打包了。 -4. 使用*MyAutoValue*。在*MyAutoValueClassTest*类上注解*MyAutoValue*。编译 +4. 使用*MyAutoValue*。在*MyAutoValueClassTest*类上注解*MyAutoValue*。 ``` @MyAutoValue public class MyAutoValueClassTest { @@ -158,7 +160,7 @@ public @interface MyAutoValue { private int c; } ``` -编译完后就会生成一下的类。 +编译完后就会生成以下的新类,会发现自定带上了get,set和toString的方法。 ``` public class MyAutoValueClassTest_MyAutoValue { private String a; @@ -190,4 +192,4 @@ public class MyAutoValueClassTest_MyAutoValue { } ``` ### 结语 -dagger的实现跟AutoValue类似,也是根据注解嵌入编译实现新的类,只是AutoValue的逻辑比较简单,只是实现ValueClass的构造,dagger会涉及到更多依赖注入的功能,dagger也依赖了AutoValue来实现了很多功能。后面会介绍更多dagger的内容。 \ No newline at end of file +dagger的实现跟AutoValue类似,也是根据注解嵌入编译实现新的类,只是AutoValue的逻辑比较简单,只是实现ValueClass的构造,dagger会涉及到更多依赖注入的功能。后面会介绍更多dagger的内容。 \ No newline at end of file From 09dbca73d6855ddf332503337d8d1ad3a232eeca Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 30 Nov 2016 11:33:46 +0800 Subject: [PATCH 28/96] save --- doc/dagger/AutoValue.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/dagger/AutoValue.md b/doc/dagger/AutoValue.md index 0bdb602..fd38dcd 100644 --- a/doc/dagger/AutoValue.md +++ b/doc/dagger/AutoValue.md @@ -13,7 +13,7 @@ AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建 } ``` 2. 注册*processor*,AutoValue的jar包中的*META-INF/services*路径里面包含文件*javax.annotation.processing.Processor*,文件里包含了注册的*processor*,换行分割。这里面注册了*AutoValueProcessor*。 -3. *AutoValueProcessor*的*process*方法实现了主要的处理逻辑,读取注释的类的信息,构造新的类,并写入文件。 +3. *AutoValueProcessor*的*process*方法实现了主要的处理逻辑,读取注释的类的信息,构造新的类,并写入文件。*processType*方法是处理单个类的方法,主要的逻辑如下 ``` AutoValueTemplateVars vars = new AutoValueTemplateVars(); vars.pkg = TypeSimplifier.packageNameOf(type); @@ -191,5 +191,6 @@ public class MyAutoValueClassTest_MyAutoValue { } } ``` + ### 结语 dagger的实现跟AutoValue类似,也是根据注解嵌入编译实现新的类,只是AutoValue的逻辑比较简单,只是实现ValueClass的构造,dagger会涉及到更多依赖注入的功能。后面会介绍更多dagger的内容。 \ No newline at end of file From f95dbd1c317e66a2a99585a1f93861e100b0f770 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 4 Dec 2016 18:06:12 +0800 Subject: [PATCH 29/96] provides test --- annotation/pom.xml | 10 ++ .../com/wcong/test/mydagger/MyComponent.java | 15 +++ .../test/mydagger/MyComponentProcessor.java | 21 ++++ .../wcong/test/mydagger/MyComponentStep.java | 30 +++++ .../com/wcong/test/mydagger/MyInject.java | 8 ++ .../com/wcong/test/mydagger/MyProvides.java | 17 +++ .../wcong/test/mydagger/MyProvidesStep.java | 115 ++++++++++++++++++ .../javax.annotation.processing.Processor | 3 +- .../wcong/test/mydagger/MyProvidesTest.java | 12 ++ 9 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyInject.java create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java create mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java create mode 100644 src/main/java/org/wcong/test/mydagger/MyProvidesTest.java diff --git a/annotation/pom.xml b/annotation/pom.xml index a35e687..5c37959 100644 --- a/annotation/pom.xml +++ b/annotation/pom.xml @@ -16,6 +16,16 @@ javapoet 1.7.0 + + com.google.auto + auto-common + 0.8 + + + javax.inject + javax.inject + 1 + diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java b/annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java new file mode 100644 index 0000000..eada7ce --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java @@ -0,0 +1,15 @@ +package com.wcong.test.mydagger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author wcong + * @since 2016/12/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyComponent { +} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java b/annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java new file mode 100644 index 0000000..4b79cc6 --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java @@ -0,0 +1,21 @@ +package com.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; + +import java.util.ArrayList; +import java.util.List; + +/** + * my component processor + * + * @author wcong + * @since 2016/12/4 + */ +public class MyComponentProcessor extends BasicAnnotationProcessor { + @Override + protected Iterable initSteps() { + List processingStepList = new ArrayList<>(); + processingStepList.add(new MyProvidesStep(processingEnv.getFiler(), processingEnv.getMessager())); + return processingStepList; + } +} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java b/annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java new file mode 100644 index 0000000..ce268c5 --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java @@ -0,0 +1,30 @@ +package com.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.common.collect.SetMultimap; + +import javax.lang.model.element.Element; +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.Set; + +/** + * process step ,do it last. + * export one class,make all provide class + * + * @author wcong + * @since 2016/12/4 + */ +public class MyComponentStep implements BasicAnnotationProcessor.ProcessingStep { + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyComponent.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + return null; + } +} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyInject.java b/annotation/src/main/java/com/wcong/test/mydagger/MyInject.java new file mode 100644 index 0000000..aa92b0d --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyInject.java @@ -0,0 +1,8 @@ +package com.wcong.test.mydagger; + +/** + * @author wcong + * @since 2016/12/4 + */ +public class MyInject { +} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java b/annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java new file mode 100644 index 0000000..7af9a76 --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java @@ -0,0 +1,17 @@ +package com.wcong.test.mydagger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * my provides + * + * @author wcong + * @since 2016/12/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface MyProvides { +} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java new file mode 100644 index 0000000..b374d26 --- /dev/null +++ b/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java @@ -0,0 +1,115 @@ +package com.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.inject.Provider; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author wcong + * @since 2016/12/4 + */ +public class MyProvidesStep implements BasicAnnotationProcessor.ProcessingStep { + + private Filer filer; + + private Messager messager; + + public MyProvidesStep(Filer filer, Messager messager) { + this.messager = messager; + this.filer = filer; + } + + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyProvides.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + Set provideElements = elementsByAnnotation.get(MyProvides.class); + if (provideElements == null || provideElements.isEmpty()) { + return Collections.emptySet(); + } + for (Element element : provideElements) { + processProvideElement(element); + } + return Collections.emptySet(); + } + + private void processProvideElement(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = element.getSimpleName() + "_MyAutoValue_Factory"; + ParameterizedTypeName superClass = ParameterizedTypeName + .get(ClassName.get(Provider.class), TypeName.get(element.asType())); + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addSuperinterface(superClass); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + typeSpecBuilder.addMethod(makeGetMethod(typeElement)); + typeSpecBuilder.addMethod(makeCreateMethod(className, superClass)); + + String packageName = getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + try { + JavaFileObject sourceFile = filer.createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } + + private MethodSpec makeGetMethod(TypeElement typeElement) { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get"); + getMethodSpecBuilder.returns(TypeName.get(typeElement.asType())); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.addCode("return new " + typeElement.getSimpleName() + "();\n"); + return getMethodSpecBuilder.build(); + } + + private MethodSpec makeCreateMethod(String className, ParameterizedTypeName superClass) { + MethodSpec.Builder createMethodSpecBuilder = MethodSpec.methodBuilder("create"); + createMethodSpecBuilder.returns(superClass); + createMethodSpecBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC); + createMethodSpecBuilder.addCode("return new " + className + "();\n"); + return createMethodSpecBuilder.build(); + } + + private String getPackageName(Element typeElement) { + while (true) { + Element enclosingElement = typeElement.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + typeElement = enclosingElement; + } + } +} diff --git a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor index e88cbd1..5f398a7 100644 --- a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1 +1,2 @@ -org.wcong.test.autovalue.MyAutoValueProcessor \ No newline at end of file +org.wcong.test.autovalue.MyAutoValueProcessor +com.wcong.test.mydagger.MyComponentProcessor \ No newline at end of file diff --git a/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java new file mode 100644 index 0000000..fbc6961 --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java @@ -0,0 +1,12 @@ +package org.wcong.test.mydagger; + +import com.wcong.test.mydagger.MyProvides; + +/** + * @author wcong + * @since 2016/12/4 + */ +@MyProvides +public class MyProvidesTest { + +} From e22b4c0054c970fe9ce1b2cf3125319ce50d30e4 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 6 Dec 2016 15:03:36 +0800 Subject: [PATCH 30/96] add provides --- .../wcong/test/mydagger/MyProvidesStep.java | 115 ---------- .../wcong/test/mydagger/MyComponent.java | 2 +- .../test/mydagger/MyComponentProcessor.java | 2 +- .../wcong/test/mydagger/MyComponentStep.java | 2 +- .../wcong/test/mydagger/MyInject.java | 2 +- .../wcong/test/mydagger/MyProvides.java | 2 +- .../wcong/test/mydagger/MyProvidesStep.java | 203 ++++++++++++++++++ .../java/org/wcong/test/util/ListUtils.java | 24 +++ .../javax.annotation.processing.Processor | 2 +- .../wcong/test/mydagger/MyProvidesTest.java | 7 +- .../wcong/test/mydagger/MyProvidesTest1.java | 8 + 11 files changed, 247 insertions(+), 122 deletions(-) delete mode 100644 annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java rename annotation/src/main/java/{com => org}/wcong/test/mydagger/MyComponent.java (90%) rename annotation/src/main/java/{com => org}/wcong/test/mydagger/MyComponentProcessor.java (94%) rename annotation/src/main/java/{com => org}/wcong/test/mydagger/MyComponentStep.java (95%) rename annotation/src/main/java/{com => org}/wcong/test/mydagger/MyInject.java (74%) rename annotation/src/main/java/{com => org}/wcong/test/mydagger/MyProvides.java (91%) create mode 100644 annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java create mode 100644 annotation/src/main/java/org/wcong/test/util/ListUtils.java create mode 100644 src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java deleted file mode 100644 index b374d26..0000000 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyProvidesStep.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.wcong.test.mydagger; - -import com.google.auto.common.BasicAnnotationProcessor; -import com.google.common.collect.SetMultimap; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; - -import javax.annotation.processing.Filer; -import javax.annotation.processing.Messager; -import javax.inject.Provider; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; -import javax.tools.Diagnostic; -import javax.tools.JavaFileObject; -import java.io.IOException; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * @author wcong - * @since 2016/12/4 - */ -public class MyProvidesStep implements BasicAnnotationProcessor.ProcessingStep { - - private Filer filer; - - private Messager messager; - - public MyProvidesStep(Filer filer, Messager messager) { - this.messager = messager; - this.filer = filer; - } - - @Override - public Set> annotations() { - Set> classSet = new HashSet<>(); - classSet.add(MyProvides.class); - return classSet; - } - - @Override - public Set process(SetMultimap, Element> elementsByAnnotation) { - Set provideElements = elementsByAnnotation.get(MyProvides.class); - if (provideElements == null || provideElements.isEmpty()) { - return Collections.emptySet(); - } - for (Element element : provideElements) { - processProvideElement(element); - } - return Collections.emptySet(); - } - - private void processProvideElement(Element element) { - TypeElement typeElement = (TypeElement) element; - String className = element.getSimpleName() + "_MyAutoValue_Factory"; - ParameterizedTypeName superClass = ParameterizedTypeName - .get(ClassName.get(Provider.class), TypeName.get(element.asType())); - TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); - typeSpecBuilder.addSuperinterface(superClass); - typeSpecBuilder.addModifiers(Modifier.PUBLIC); - typeSpecBuilder.addMethod(makeGetMethod(typeElement)); - typeSpecBuilder.addMethod(makeCreateMethod(className, superClass)); - - String packageName = getPackageName(typeElement); - JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); - String text = javaFileBuilder.build().toString(); - - try { - JavaFileObject sourceFile = filer.createSourceFile(className, element); - Writer writer = sourceFile.openWriter(); - try { - writer.write(text); - } finally { - writer.close(); - } - } catch (IOException e) { - messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); - } - } - - private MethodSpec makeGetMethod(TypeElement typeElement) { - MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get"); - getMethodSpecBuilder.returns(TypeName.get(typeElement.asType())); - getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); - getMethodSpecBuilder.addCode("return new " + typeElement.getSimpleName() + "();\n"); - return getMethodSpecBuilder.build(); - } - - private MethodSpec makeCreateMethod(String className, ParameterizedTypeName superClass) { - MethodSpec.Builder createMethodSpecBuilder = MethodSpec.methodBuilder("create"); - createMethodSpecBuilder.returns(superClass); - createMethodSpecBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC); - createMethodSpecBuilder.addCode("return new " + className + "();\n"); - return createMethodSpecBuilder.build(); - } - - private String getPackageName(Element typeElement) { - while (true) { - Element enclosingElement = typeElement.getEnclosingElement(); - if (enclosingElement instanceof PackageElement) { - return ((PackageElement) enclosingElement).getQualifiedName().toString(); - } - typeElement = enclosingElement; - } - } -} diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java similarity index 90% rename from annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java rename to annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java index eada7ce..a31b0bb 100644 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyComponent.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java @@ -1,4 +1,4 @@ -package com.wcong.test.mydagger; +package org.wcong.test.mydagger; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java similarity index 94% rename from annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java rename to annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java index 4b79cc6..7f86e5a 100644 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentProcessor.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java @@ -1,4 +1,4 @@ -package com.wcong.test.mydagger; +package org.wcong.test.mydagger; import com.google.auto.common.BasicAnnotationProcessor; diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java similarity index 95% rename from annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java rename to annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java index ce268c5..6691a9f 100644 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyComponentStep.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java @@ -1,4 +1,4 @@ -package com.wcong.test.mydagger; +package org.wcong.test.mydagger; import com.google.auto.common.BasicAnnotationProcessor; import com.google.common.collect.SetMultimap; diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyInject.java b/annotation/src/main/java/org/wcong/test/mydagger/MyInject.java similarity index 74% rename from annotation/src/main/java/com/wcong/test/mydagger/MyInject.java rename to annotation/src/main/java/org/wcong/test/mydagger/MyInject.java index aa92b0d..0f52dad 100644 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyInject.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyInject.java @@ -1,4 +1,4 @@ -package com.wcong.test.mydagger; +package org.wcong.test.mydagger; /** * @author wcong diff --git a/annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java similarity index 91% rename from annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java rename to annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java index 7af9a76..7d29e78 100644 --- a/annotation/src/main/java/com/wcong/test/mydagger/MyProvides.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java @@ -1,4 +1,4 @@ -package com.wcong.test.mydagger; +package org.wcong.test.mydagger; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java new file mode 100644 index 0000000..889a6fb --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java @@ -0,0 +1,203 @@ +package org.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import org.wcong.test.util.ListUtils; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author wcong + * @since 2016/12/4 + */ +public class MyProvidesStep implements BasicAnnotationProcessor.ProcessingStep { + + private Filer filer; + + private Messager messager; + + public MyProvidesStep(Filer filer, Messager messager) { + this.messager = messager; + this.filer = filer; + } + + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyProvides.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + Set provideElements = elementsByAnnotation.get(MyProvides.class); + if (provideElements == null || provideElements.isEmpty()) { + return Collections.emptySet(); + } + for (Element element : provideElements) { + processProvideElement(element); + } + return Collections.emptySet(); + } + + private void processProvideElement(Element element) { + TypeElement typeElement = (TypeElement) element; + + String className = element.getSimpleName() + "_MyAutoValue_Factory"; + ParameterizedTypeName superClass = ParameterizedTypeName.get(ClassName.get(Provider.class), TypeName.get(element.asType())); + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addSuperinterface(superClass); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + List injectParams = getInjectConstructMethod(typeElement); + Map typeNameMap = makeProvideParams(injectParams); + if( !typeNameMap.isEmpty() ){ + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ){ + typeSpecBuilder.addField(typeNameEntry.getValue(),typeNameEntry.getKey(),Modifier.PRIVATE,Modifier.FINAL); + } + typeSpecBuilder.addMethod(makeContructMethod(typeNameMap)); + } + typeSpecBuilder.addMethod(makeGetMethod(typeElement,typeNameMap)); + typeSpecBuilder.addMethod(makeCreateMethod(className, superClass,typeNameMap)); + + String packageName = getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + try { + JavaFileObject sourceFile = filer.createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } + + private MethodSpec makeContructMethod(Map typeNameMap){ + MethodSpec.Builder contructMethod = MethodSpec.constructorBuilder(); + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ){ + contructMethod.addParameter(typeNameEntry.getValue(),typeNameEntry.getKey()); + contructMethod.addCode("this."+typeNameEntry.getKey()+"="+typeNameEntry.getKey()+";\n"); + } + return contructMethod.build(); + } + + private Map makeProvideParams(List injectParams){ + if( injectParams.isEmpty() ){ + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + for(TypeMirror typeMirror : injectParams){ + String[] splitArray = typeMirror.toString().split("\\."); + map.put(splitArray[splitArray.length-1],ParameterizedTypeName.get(ClassName.get(Provider.class),TypeName.get(typeMirror))); + } + return map; + } + + private List getInjectConstructMethod(TypeElement typeElement){ + for(Element element : typeElement.getEnclosedElements() ){ + if( ! (element instanceof ExecutableElement)){ + continue; + } + ExecutableElement executableElement = (ExecutableElement) element; + if( !"".equals(executableElement.getSimpleName().toString()) ){ + continue; + } + Inject inject = executableElement.getAnnotation(Inject.class); + if( inject == null ){ + continue; + } + List variableElementList = executableElement.getParameters(); + if( !variableElementList.isEmpty() ){ + List typeMirrors = new ArrayList<>(variableElementList.size()); + for( VariableElement variableElement : variableElementList ){ + typeMirrors.add(variableElement.asType()); + } + return typeMirrors; + } + } + return Collections.emptyList(); + } + + private MethodSpec makeGetMethod(TypeElement typeElement,Map typeNameMap ) { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get"); + getMethodSpecBuilder.returns(TypeName.get(typeElement.asType())); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + if( typeNameMap.isEmpty() ) { + getMethodSpecBuilder.addCode("return new " + typeElement.getSimpleName() + "();\n"); + }else{ + StringBuilder construct = new StringBuilder(); + construct.append("return new ").append( typeElement.getSimpleName()).append("("); + List paramList = new ArrayList<>(typeNameMap.size()); + for( Map.Entry typeNameEntry :typeNameMap.entrySet()){ + paramList.add(typeNameEntry.getKey()+".get()"); + } + construct.append(ListUtils.implode(paramList,",")).append(");\n"); + getMethodSpecBuilder.addCode(construct.toString()); + } + return getMethodSpecBuilder.build(); + } + + private MethodSpec makeCreateMethod(String className, ParameterizedTypeName superClass,Map typeNameMap ) { + MethodSpec.Builder createMethodSpecBuilder = MethodSpec.methodBuilder("create"); + createMethodSpecBuilder.returns(superClass); + if( !typeNameMap.isEmpty() ){ + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ) { + createMethodSpecBuilder.addParameter(typeNameEntry.getValue(),typeNameEntry.getKey()); + } + } + createMethodSpecBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC); + if( typeNameMap.isEmpty() ) { + createMethodSpecBuilder.addCode("return new " + className + "();\n"); + }else{ + createMethodSpecBuilder.addCode("return new "+className+"("); + List paramList = new ArrayList<>(typeNameMap.size()); + for( Map.Entry typeNameEntry:typeNameMap.entrySet() ){ + paramList.add(typeNameEntry.getKey()); + } + createMethodSpecBuilder.addCode(ListUtils.implode(paramList,",")+");\n"); + } + return createMethodSpecBuilder.build(); + } + + private String getPackageName(Element typeElement) { + while (true) { + Element enclosingElement = typeElement.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + typeElement = enclosingElement; + } + } +} diff --git a/annotation/src/main/java/org/wcong/test/util/ListUtils.java b/annotation/src/main/java/org/wcong/test/util/ListUtils.java new file mode 100644 index 0000000..b5c2708 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/util/ListUtils.java @@ -0,0 +1,24 @@ +package org.wcong.test.util; + +import java.util.Iterator; +import java.util.List; + +/** + * Created by wcong on 2016/12/6. + */ +public class ListUtils { + + public static String implode(List list, String joint) { + if (list == null || list.isEmpty()) { + return ""; + } + Iterator iterator = list.iterator(); + StringBuilder sb = new StringBuilder(); + sb.append(iterator.next()); + while (iterator.hasNext()) { + sb.append(joint).append(iterator.next()); + } + return sb.toString(); + } + +} diff --git a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor index 5f398a7..8783c37 100644 --- a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,2 +1,2 @@ org.wcong.test.autovalue.MyAutoValueProcessor -com.wcong.test.mydagger.MyComponentProcessor \ No newline at end of file +org.wcong.test.mydagger.MyComponentProcessor \ No newline at end of file diff --git a/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java index fbc6961..d3d10e8 100644 --- a/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java +++ b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java @@ -1,6 +1,6 @@ package org.wcong.test.mydagger; -import com.wcong.test.mydagger.MyProvides; +import javax.inject.Inject; /** * @author wcong @@ -9,4 +9,9 @@ @MyProvides public class MyProvidesTest { + @Inject + public MyProvidesTest(MyProvidesTest1 myProvidesTest1) { + + } + } diff --git a/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java b/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java new file mode 100644 index 0000000..fbbfda8 --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java @@ -0,0 +1,8 @@ +package org.wcong.test.mydagger; + +/** + * Created by wcong on 2016/12/6. + */ +@MyProvides +public class MyProvidesTest1 { +} From 20fe766d06535115b82802e93656df704c3710d8 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 7 Dec 2016 15:29:19 +0800 Subject: [PATCH 31/96] add my component --- .../test/mydagger/MyComponentProcessor.java | 23 ++- .../wcong/test/mydagger/MyComponentStep.java | 156 ++++++++++++++++-- .../wcong/test/mydagger/MyProvidesStep.java | 22 ++- .../org/wcong/test/util/ElementUtils.java | 19 +++ .../wcong/test/mydagger/MyComponentTest.java | 11 ++ 5 files changed, 202 insertions(+), 29 deletions(-) create mode 100644 annotation/src/main/java/org/wcong/test/util/ElementUtils.java create mode 100644 src/main/java/org/wcong/test/mydagger/MyComponentTest.java diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java index 7f86e5a..2db6fdf 100644 --- a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java @@ -1,9 +1,14 @@ package org.wcong.test.mydagger; import com.google.auto.common.BasicAnnotationProcessor; +import com.squareup.javapoet.ParameterizedTypeName; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * my component processor @@ -12,10 +17,16 @@ * @since 2016/12/4 */ public class MyComponentProcessor extends BasicAnnotationProcessor { - @Override - protected Iterable initSteps() { - List processingStepList = new ArrayList<>(); - processingStepList.add(new MyProvidesStep(processingEnv.getFiler(), processingEnv.getMessager())); - return processingStepList; - } + + private Map> dependencyMap = new HashMap<>(); + + @Override + protected Iterable initSteps() { + Filer filer = processingEnv.getFiler(); + Messager messager = processingEnv.getMessager(); + List processingStepList = new ArrayList<>(); + processingStepList.add(new MyProvidesStep(filer, messager, dependencyMap)); + processingStepList.add(new MyComponentStep(filer, messager, dependencyMap)); + return processingStepList; + } } diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java index 6691a9f..3aa974a 100644 --- a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java @@ -2,10 +2,36 @@ import com.google.auto.common.BasicAnnotationProcessor; import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import org.wcong.test.util.ElementUtils; +import org.wcong.test.util.ListUtils; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.inject.Provider; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -16,15 +42,123 @@ * @since 2016/12/4 */ public class MyComponentStep implements BasicAnnotationProcessor.ProcessingStep { - @Override - public Set> annotations() { - Set> classSet = new HashSet<>(); - classSet.add(MyComponent.class); - return classSet; - } - - @Override - public Set process(SetMultimap, Element> elementsByAnnotation) { - return null; - } + private Filer filer; + + private Messager messager; + + private Map> dependencyMap; + + public MyComponentStep(Filer filer, Messager messager, Map> dependencyMap) { + this.messager = messager; + this.filer = filer; + this.dependencyMap = dependencyMap; + } + + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyComponent.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + Set elementSet = elementsByAnnotation.get(MyComponent.class); + try { + for (Element element : elementSet) { + processComponent(element); + } + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + return Collections.emptySet(); + } + + private void processComponent(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = "MyDagger_" + typeElement.getSimpleName().toString(); + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addSuperinterface(TypeName.get(element.asType())); + List startTypeName = new ArrayList<>(10); + List methodList = ElementFilter.methodsIn(element.getEnclosedElements()); + Map typeParameterizedMap = new HashMap<>(); + for (ExecutableElement executableElement : methodList) { + TypeMirror returnType = executableElement.getReturnType(); + ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(ClassName.get(Provider.class), TypeName.get(returnType)); + typeParameterizedMap.put(returnType, parameterizedTypeName); + startTypeName.add(parameterizedTypeName); + } + Set fieldInitialList = new LinkedHashSet<>(dependencyMap.size()); + for (ParameterizedTypeName parameterizedTypeName : startTypeName) { + ergodicDependency(parameterizedTypeName, fieldInitialList); + } + Map fieldNameMap = generateFieldMap(fieldInitialList); + for (ParameterizedTypeName field : fieldInitialList) { + typeSpecBuilder.addField(field, fieldNameMap.get(field), Modifier.PRIVATE); + } + + MethodSpec.Builder constructBuilder = MethodSpec.constructorBuilder(); + for (ParameterizedTypeName field : fieldInitialList) { + String fieldName = fieldNameMap.get(field); + List dependencyList = dependencyMap.get(field); + if (dependencyList == null || dependencyList.isEmpty()) { + constructBuilder.addCode("this." + fieldName + "=" + fieldName + "_MyDagger_Factory.create();\n"); + } else { + List paramList = new ArrayList<>(dependencyList.size()); + for (ParameterizedTypeName parameterizedTypeName : dependencyList) { + paramList.add(fieldNameMap.get(parameterizedTypeName)); + } + constructBuilder.addCode("this." + fieldName + "=" + fieldName + "_MyDagger_Factory.create(" + ListUtils.implode(paramList, ",") + ");\n"); + } + } + typeSpecBuilder.addMethod(constructBuilder.build()); + + for (ExecutableElement method : methodList) { + MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()); + methodBuilder.returns(TypeName.get(method.getReturnType())); + methodBuilder.addModifiers(Modifier.PUBLIC); + methodBuilder.addCode("return " + fieldNameMap.get(typeParameterizedMap.get(method.getReturnType())) + ".get();\n"); + typeSpecBuilder.addMethod(methodBuilder.build()); + } + + String packageName = ElementUtils.getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + try { + JavaFileObject sourceFile = filer.createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } + + private Map generateFieldMap(Set fieldInitialList) { + Map fieldNameMap = new HashMap<>(); + for (ParameterizedTypeName field : fieldInitialList) { + String firstClass = field.typeArguments.get(0).toString(); + String[] fieldNameArray = firstClass.split("\\."); + String fieldName = fieldNameArray[fieldNameArray.length - 1]; + fieldNameMap.put(field, fieldName); + } + return fieldNameMap; + } + + private void ergodicDependency(ParameterizedTypeName parameterizedTypeName, Set fieldInitialList) { + List dependencyList = dependencyMap.get(parameterizedTypeName); + if (dependencyList != null && !dependencyList.isEmpty()) { + for (ParameterizedTypeName innerParameterizedTypeName : dependencyList) { + if (fieldInitialList.contains(innerParameterizedTypeName)) { + continue; + } + ergodicDependency(innerParameterizedTypeName, fieldInitialList); + } + } + fieldInitialList.add(parameterizedTypeName); + } } diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java index 889a6fb..86d4cfc 100644 --- a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java @@ -8,6 +8,7 @@ import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; +import org.wcong.test.util.ElementUtils; import org.wcong.test.util.ListUtils; import javax.annotation.processing.Filer; @@ -44,9 +45,12 @@ public class MyProvidesStep implements BasicAnnotationProcessor.ProcessingStep { private Messager messager; - public MyProvidesStep(Filer filer, Messager messager) { + private Map> dependencyMap; + + public MyProvidesStep(Filer filer, Messager messager,Map> dependencyMap) { this.messager = messager; this.filer = filer; + this.dependencyMap = dependencyMap; } @Override @@ -71,7 +75,7 @@ public Set process(SetMultimap, Element> el private void processProvideElement(Element element) { TypeElement typeElement = (TypeElement) element; - String className = element.getSimpleName() + "_MyAutoValue_Factory"; + String className = element.getSimpleName() + "_MyDagger_Factory"; ParameterizedTypeName superClass = ParameterizedTypeName.get(ClassName.get(Provider.class), TypeName.get(element.asType())); TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); typeSpecBuilder.addSuperinterface(superClass); @@ -79,15 +83,18 @@ private void processProvideElement(Element element) { List injectParams = getInjectConstructMethod(typeElement); Map typeNameMap = makeProvideParams(injectParams); if( !typeNameMap.isEmpty() ){ + List dependencyList = new ArrayList<>(typeNameMap.size()); for( Map.Entry typeNameEntry : typeNameMap.entrySet() ){ + dependencyList.add(typeNameEntry.getValue()); typeSpecBuilder.addField(typeNameEntry.getValue(),typeNameEntry.getKey(),Modifier.PRIVATE,Modifier.FINAL); } + dependencyMap.put(superClass,dependencyList); typeSpecBuilder.addMethod(makeContructMethod(typeNameMap)); } typeSpecBuilder.addMethod(makeGetMethod(typeElement,typeNameMap)); typeSpecBuilder.addMethod(makeCreateMethod(className, superClass,typeNameMap)); - String packageName = getPackageName(typeElement); + String packageName = ElementUtils.getPackageName(typeElement); JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); String text = javaFileBuilder.build().toString(); @@ -191,13 +198,4 @@ private MethodSpec makeCreateMethod(String className, ParameterizedTypeName supe return createMethodSpecBuilder.build(); } - private String getPackageName(Element typeElement) { - while (true) { - Element enclosingElement = typeElement.getEnclosingElement(); - if (enclosingElement instanceof PackageElement) { - return ((PackageElement) enclosingElement).getQualifiedName().toString(); - } - typeElement = enclosingElement; - } - } } diff --git a/annotation/src/main/java/org/wcong/test/util/ElementUtils.java b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java new file mode 100644 index 0000000..a393c4a --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java @@ -0,0 +1,19 @@ +package org.wcong.test.util; + +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; + +/** + * Created by wcong on 2016/12/6. + */ +public class ElementUtils { + public static String getPackageName(Element element) { + while (true) { + Element enclosingElement = element.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + element = enclosingElement; + } + } +} diff --git a/src/main/java/org/wcong/test/mydagger/MyComponentTest.java b/src/main/java/org/wcong/test/mydagger/MyComponentTest.java new file mode 100644 index 0000000..65876da --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyComponentTest.java @@ -0,0 +1,11 @@ +package org.wcong.test.mydagger; + +/** + * Created by wcong on 2016/12/7. + */ +@MyComponent +public interface MyComponentTest { + + MyProvidesTest myProvidesTest(); + +} From 761a4e6c4b54796d0d61ef9286cdc0e380890814 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 7 Dec 2016 16:29:06 +0800 Subject: [PATCH 32/96] optimize --- .../wcong/test/mydagger/MyComponentStep.java | 31 +++++++++---------- .../wcong/test/mydagger/MyProvidesStep.java | 13 ++------ .../org/wcong/test/util/ElementUtils.java | 20 ++++++++++++ 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java index 3aa974a..661adcd 100644 --- a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java @@ -79,6 +79,7 @@ private void processComponent(Element element) { String className = "MyDagger_" + typeElement.getSimpleName().toString(); TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); typeSpecBuilder.addSuperinterface(TypeName.get(element.asType())); + List startTypeName = new ArrayList<>(10); List methodList = ElementFilter.methodsIn(element.getEnclosedElements()); Map typeParameterizedMap = new HashMap<>(); @@ -97,6 +98,18 @@ private void processComponent(Element element) { typeSpecBuilder.addField(field, fieldNameMap.get(field), Modifier.PRIVATE); } + fieldsAndConstruct(typeSpecBuilder, fieldInitialList, fieldNameMap); + + implementMethods(typeSpecBuilder, methodList, typeParameterizedMap, fieldNameMap); + + String packageName = ElementUtils.getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + ElementUtils.writeFile(filer,messager,className,text,element); + } + + private void fieldsAndConstruct(TypeSpec.Builder typeSpecBuilder, Set fieldInitialList, Map fieldNameMap) { MethodSpec.Builder constructBuilder = MethodSpec.constructorBuilder(); for (ParameterizedTypeName field : fieldInitialList) { String fieldName = fieldNameMap.get(field); @@ -112,7 +125,9 @@ private void processComponent(Element element) { } } typeSpecBuilder.addMethod(constructBuilder.build()); + } + private void implementMethods(TypeSpec.Builder typeSpecBuilder, List methodList, Map typeParameterizedMap, Map fieldNameMap) { for (ExecutableElement method : methodList) { MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()); methodBuilder.returns(TypeName.get(method.getReturnType())); @@ -120,22 +135,6 @@ private void processComponent(Element element) { methodBuilder.addCode("return " + fieldNameMap.get(typeParameterizedMap.get(method.getReturnType())) + ".get();\n"); typeSpecBuilder.addMethod(methodBuilder.build()); } - - String packageName = ElementUtils.getPackageName(typeElement); - JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); - String text = javaFileBuilder.build().toString(); - - try { - JavaFileObject sourceFile = filer.createSourceFile(className, element); - Writer writer = sourceFile.openWriter(); - try { - writer.write(text); - } finally { - writer.close(); - } - } catch (IOException e) { - messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); - } } private Map generateFieldMap(Set fieldInitialList) { diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java index 86d4cfc..8bb21ee 100644 --- a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java @@ -80,6 +80,7 @@ private void processProvideElement(Element element) { TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); typeSpecBuilder.addSuperinterface(superClass); typeSpecBuilder.addModifiers(Modifier.PUBLIC); + List injectParams = getInjectConstructMethod(typeElement); Map typeNameMap = makeProvideParams(injectParams); if( !typeNameMap.isEmpty() ){ @@ -98,17 +99,7 @@ private void processProvideElement(Element element) { JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); String text = javaFileBuilder.build().toString(); - try { - JavaFileObject sourceFile = filer.createSourceFile(className, element); - Writer writer = sourceFile.openWriter(); - try { - writer.write(text); - } finally { - writer.close(); - } - } catch (IOException e) { - messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); - } + ElementUtils.writeFile(filer,messager,className,text,element); } private MethodSpec makeContructMethod(Map typeNameMap){ diff --git a/annotation/src/main/java/org/wcong/test/util/ElementUtils.java b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java index a393c4a..eaf9f92 100644 --- a/annotation/src/main/java/org/wcong/test/util/ElementUtils.java +++ b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java @@ -1,7 +1,13 @@ package org.wcong.test.util; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; /** * Created by wcong on 2016/12/6. @@ -16,4 +22,18 @@ public static String getPackageName(Element element) { element = enclosingElement; } } + + public static void writeFile(Filer filer, Messager messager, String className, String text, Element element) { + try { + JavaFileObject sourceFile = filer.createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } } From ed1cc7045941c9c58ea58193b5f4da4c69dde9ca Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 6 Feb 2017 14:27:06 +0800 Subject: [PATCH 33/96] add heap sort --- doc/dagger/MyDagger.md | 1 + .../org/wcong/test/algorithm/HeapSort.java | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 doc/dagger/MyDagger.md create mode 100644 src/main/java/org/wcong/test/algorithm/HeapSort.java diff --git a/doc/dagger/MyDagger.md b/doc/dagger/MyDagger.md new file mode 100644 index 0000000..06d57ef --- /dev/null +++ b/doc/dagger/MyDagger.md @@ -0,0 +1 @@ +### 前言 \ No newline at end of file diff --git a/src/main/java/org/wcong/test/algorithm/HeapSort.java b/src/main/java/org/wcong/test/algorithm/HeapSort.java new file mode 100644 index 0000000..9763a15 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/HeapSort.java @@ -0,0 +1,33 @@ +package org.wcong.test.algorithm; + +/** + * Created by hzwangcong on 2017/2/5. + */ +public class HeapSort { + + public static void main(String[] args) { + + } + + static void maxHeapify(int[] array, int top) { + if (top >= array.length) { + return; + } + int left = (top + 1) * 2 - 1; + int right = (top + 1) * 2; + int large = top; + if (left < array.length && array[left] > array[large]) { + large = left; + } + if (right < array.length && array[right] > array[large]) { + large = right; + } + if (large != top) { + int temp = array[top]; + array[top] = array[large]; + array[large] = temp; + maxHeapify(array, large); + } + } + +} From 4125de2e24a7325ffea6268197fed68d175197be Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 9 Mar 2017 20:30:07 +0800 Subject: [PATCH 34/96] add sum for 3 --- src/main/java/org/wcong/App.java | 8 +- .../org/wcong/test/algorithm/BinaryTree.java | 91 +++++++++++++ .../algorithm/ContainerWithMostWater.java | 41 ++++++ .../wcong/test/algorithm/DubboLinkedInt.java | 14 ++ .../org/wcong/test/algorithm/HeapSort.java | 2 + .../org/wcong/test/algorithm/LongPrefix.java | 14 ++ .../java/org/wcong/test/algorithm/RBTree.java | 10 ++ .../org/wcong/test/algorithm/StringMatch.java | 83 ++++++++++++ .../org/wcong/test/algorithm/SumFor3.java | 123 ++++++++++++++++++ .../org/wcong/test/algorithm/graph/Edge.java | 27 ++++ .../org/wcong/test/algorithm/graph/Graph.java | 40 ++++++ .../wcong/test/algorithm/graph/Vertices.java | 18 +++ 12 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/wcong/test/algorithm/BinaryTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java create mode 100644 src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java create mode 100644 src/main/java/org/wcong/test/algorithm/LongPrefix.java create mode 100644 src/main/java/org/wcong/test/algorithm/RBTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/StringMatch.java create mode 100644 src/main/java/org/wcong/test/algorithm/SumFor3.java create mode 100644 src/main/java/org/wcong/test/algorithm/graph/Edge.java create mode 100644 src/main/java/org/wcong/test/algorithm/graph/Graph.java create mode 100644 src/main/java/org/wcong/test/algorithm/graph/Vertices.java diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index 68e5218..4465bf7 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -2,7 +2,10 @@ import java.lang.reflect.ParameterizedType; import java.math.BigDecimal; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -13,7 +16,10 @@ public class App { static int a; public static void main(String[] args) { - System.out.println(a); + DateFormat format = new SimpleDateFormat("M月d日"); + System.out.println(format.format(new Date(2011,11,2))); + System.out.println(format.format(new Date(2011,0,12))); + System.out.println(format.format(new Date(2011,3,12))); } public static Class findSuperClassParameterType(Object instance, int parameterIndex) { diff --git a/src/main/java/org/wcong/test/algorithm/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/BinaryTree.java new file mode 100644 index 0000000..0eeb70f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/BinaryTree.java @@ -0,0 +1,91 @@ +package org.wcong.test.algorithm; + +/** + * Created by hzwangcong on 2017/2/7. + */ +public class BinaryTree { + + private Node root; + + public static void main(String[] args) { + + } + + public void add(int value){ + if( root == null ){ + root = new Node(); + root.value = value; + return; + } + Node last = root; + while (true){ + Node next; + if( value < last.value ){ + next = last.left; + if( next == null ){ + Node newNode = new Node(); + newNode.value = value; + last.left = newNode; + }else{ + last = next; + } + }else{ + next = last.right; + if( next == null ){ + Node newNode = new Node(); + newNode.value = value; + last.right = newNode; + }else{ + last = next; + } + } + } + } + + DubboLinkedInt binaryTreeToLink() { + if( root == null ){ + return null; + } + DubboLinkedInt middle = new DubboLinkedInt(); + middle.value = root.value; + recurrentLink(root,middle); + DubboLinkedInt first = middle; + while (first.left!=null){ + first = first.left; + } + return first; + } + + private void recurrentLink( Node parentNode,DubboLinkedInt parentInt ){ + if( parentNode.left != null ){ + DubboLinkedInt leftInt = new DubboLinkedInt(); + leftInt.value = parentNode.left.value; + leftInt.right = parentInt; + if( parentInt.left != null ) { + DubboLinkedInt tempInt = parentInt.left; + parentInt.left = leftInt; + leftInt.left = tempInt; + } + recurrentLink(parentNode.left , leftInt); + } + if( parentNode.right != null ){ + DubboLinkedInt rightInt = new DubboLinkedInt(); + rightInt.value = parentNode.right.value; + rightInt.left = parentInt; + if(parentInt.right != null) { + DubboLinkedInt tempInt = parentInt.right; + parentInt.right = rightInt; + rightInt.right = tempInt; + } + recurrentLink(parentNode.right, rightInt); + } + } + + static class Node { + int value; + + Node left; + + Node right; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java b/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java new file mode 100644 index 0000000..8ebdc5e --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm; + +import org.eclipse.core.runtime.Assert; + +/** + * Given n non-negative integers a1, a2, ..., an, + * where each represents a point at coordinate (i, ai). + * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). + * Find two lines, which together with x-axis forms a container, such that the container contains the most water. + * Note: You may not slant the container and n is at least 2. + * Created by hzwangcong on 2017/3/1. + */ +public class ContainerWithMostWater { + + public static void main(String[] args) { + Assert.isTrue(maxArea(new int[]{1, 2}) == 1); + Assert.isTrue(maxArea(new int[]{1, 2, 1}) == 2); + Assert.isTrue(maxArea(new int[]{3, 2, 1, 3}) == 9); + } + + /** + * go to next element + * second height + */ + public static int maxArea(int[] height) { + int left = 0, right = height.length - 1; + int maxArea = 0; + + while (left < right) { + maxArea = Math.max(maxArea, Math.min(height[left], height[right]) + * (right - left)); + if (height[left] < height[right]) + left++; + else + right--; + } + + return maxArea; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java b/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java new file mode 100644 index 0000000..9ade03a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java @@ -0,0 +1,14 @@ +package org.wcong.test.algorithm; + +/** + * Created by hzwangcong on 2017/2/7. + */ +public class DubboLinkedInt { + + int value; + + DubboLinkedInt left; + + DubboLinkedInt right; + +} diff --git a/src/main/java/org/wcong/test/algorithm/HeapSort.java b/src/main/java/org/wcong/test/algorithm/HeapSort.java index 9763a15..f3d38fa 100644 --- a/src/main/java/org/wcong/test/algorithm/HeapSort.java +++ b/src/main/java/org/wcong/test/algorithm/HeapSort.java @@ -1,6 +1,8 @@ package org.wcong.test.algorithm; /** + * a*b,b*c,c*d,d*e + * * Created by hzwangcong on 2017/2/5. */ public class HeapSort { diff --git a/src/main/java/org/wcong/test/algorithm/LongPrefix.java b/src/main/java/org/wcong/test/algorithm/LongPrefix.java new file mode 100644 index 0000000..772f1b8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/LongPrefix.java @@ -0,0 +1,14 @@ +package org.wcong.test.algorithm; + +/** + * Write a function to find the longest common prefix string amongst an array of strings. + * Created by hzwangcong on 2017/3/1. + */ +public class LongPrefix { + + public static void main(String[] args) { + + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/RBTree.java b/src/main/java/org/wcong/test/algorithm/RBTree.java new file mode 100644 index 0000000..da0544d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/RBTree.java @@ -0,0 +1,10 @@ +package org.wcong.test.algorithm; + +/** + * Created by hzwangcong on 2017/2/6. + */ +public class RBTree { + public static void main(String[] args) { + + } +} diff --git a/src/main/java/org/wcong/test/algorithm/StringMatch.java b/src/main/java/org/wcong/test/algorithm/StringMatch.java new file mode 100644 index 0000000..7457d52 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/StringMatch.java @@ -0,0 +1,83 @@ +package org.wcong.test.algorithm; + +import org.eclipse.core.runtime.Assert; + +/** + * . means anyone char + * * means none or many preceding + * Created by hzwangcong on 2017/2/14. + */ +public class StringMatch { + + public static void main(String[] args) { + Assert.isTrue(matchPart("abcd", "c*abcd")); + Assert.isTrue(!matchPart("abcdefg", "abcdef*")); + Assert.isTrue(matchPart("abcdefg", "abcde.*")); + Assert.isTrue(matchPart("abcdefgbcd", "abcde.*cd")); + Assert.isTrue(matchPart("aab", "a*b")); + Assert.isTrue(matchPart("aaaab", "aa*ab")); + Assert.isTrue(matchPart("abcd", ".bcd")); + Assert.isTrue(matchPart("abcd", "a.*")); + Assert.isTrue(matchPart("a", "ab*")); + Assert.isTrue(matchPart("ab", ".*..")); + Assert.isTrue(matchPart("abcaaaaaaabaabcabac", ".*ab.a.*a*a*.*b*b*")); + } + + static boolean matchPart(String a, String b) { + return match(a, b, 0, 0); + } + + static boolean match(String a, String b, int aIndex, int bIndex) { + while (aIndex < a.length() && bIndex < b.length()) { + char aChar = a.charAt(aIndex); + char bChar = b.charAt(bIndex); + if ((bIndex + 1) < b.length() && b.charAt(bIndex + 1) == '*') { + if (bChar == '.') { + if ((bIndex + 2) < b.length()) { + bChar = b.charAt(bIndex + 2); + while (aIndex < a.length()) { + if( bChar == '.' && match(a, b, aIndex, bIndex + 2) ){ + return true; + } + aChar = a.charAt(aIndex); + if (aChar == bChar && match(a, b, aIndex, bIndex + 2)) { + return true; + } + aIndex += 1; + } + } else { + return true; + } + } else { + if (aChar == bChar) { + while (aIndex < a.length() && aChar == a.charAt(aIndex)) { + if (match(a, b, aIndex, bIndex + 2)) { + return true; + } + aIndex += 1; + } + } + bIndex += 2; + continue; + } + } else if (bChar == '.') { + bIndex += 1; + aIndex += 1; + continue; + } else if (aChar == bChar) { + bIndex += 1; + aIndex += 1; + continue; + } + return false; + } + while (bIndex < b.length()) { + if ((bIndex + 1) < b.length() && b.charAt(bIndex + 1) == '*') { + bIndex += 2; + } else { + break; + } + } + return aIndex == a.length() && bIndex == b.length(); + } +} diff --git a/src/main/java/org/wcong/test/algorithm/SumFor3.java b/src/main/java/org/wcong/test/algorithm/SumFor3.java new file mode 100644 index 0000000..d6fff49 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/SumFor3.java @@ -0,0 +1,123 @@ +package org.wcong.test.algorithm; + +import org.eclipse.core.runtime.Assert; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? + * Find all unique triplets in the array which gives the sum of zero. + * Note: The solution set must not contain duplicate triplets. + * For example, given array S = [-1, 0, 1, 2, -1, -4], + * A solution set is: + * [ + * [-1, 0, 1], + * [-1, -1, 2] + * ] + *

+ * Created by hzwangcong on 2017/3/1. + */ +public class SumFor3 { + + public static void main(String[] args) { + + Assert.isTrue(listListEqual(treeSum(new int[]{-1, 0, 1, 2, -1, -4}), new ArrayList>(Arrays.asList(Arrays.asList(-1, 0, 1), Arrays.asList(-1, -1, 2))))); + } + + private static boolean listListEqual(List> answerList, List> sumArrays) { + Iterator> answerIterator = answerList.iterator(); + while (answerIterator.hasNext()) { + List answer = answerIterator.next(); + Iterator> sumIterator = sumArrays.iterator(); + while (sumIterator.hasNext()) { + List sum = sumIterator.next(); + if (listEqual(answer, sum)) { + sumIterator.remove(); + answerIterator.remove(); + break; + } + } + } + return answerList.isEmpty() && sumArrays.isEmpty(); + } + + private static boolean listEqual(List a, List b) { + List aTemp = new ArrayList<>(a); + List bTemp = new ArrayList<>(b); + Iterator aIterator = aTemp.iterator(); + while (aIterator.hasNext()) { + Integer aItem = aIterator.next(); + Iterator bIterator = bTemp.iterator(); + while (bIterator.hasNext()) { + Integer bItem = bIterator.next(); + if (aItem.equals(bItem)) { + bIterator.remove(); + aIterator.remove(); + break; + } + } + } + return aTemp.isEmpty() && bTemp.isEmpty(); + } + + + public static List> treeSum(int[] nums) { + List positiveSet = new ArrayList<>(); + List negativeSet = new ArrayList<>(); + int zeroNum = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 0) { + zeroNum += 1; + } else if (nums[i] < 0) { + negativeSet.add(-nums[i]); + } else { + positiveSet.add(nums[i]); + } + } + List> sumList = new ArrayList<>(); + if (zeroNum > 0) { + if (zeroNum > 2) { + List oneSum = new ArrayList<>(3); + oneSum.add(0); + oneSum.add(0); + oneSum.add(0); + sumList.add(oneSum); + } + for (Integer positive : positiveSet) { + if (negativeSet.contains(positive)) { + List oneSum = new ArrayList<>(3); + oneSum.add(0); + oneSum.add(positive); + oneSum.add(-positive); + sumList.add(oneSum); + } + } + } + sumList.addAll(sumInTwo(positiveSet, negativeSet, true)); + sumList.addAll(sumInTwo(negativeSet, positiveSet, false)); + return sumList; + } + + private static List> sumInTwo(List positiveSet, List negativeSet, boolean positive) { + List> sumList = new ArrayList<>(); + Integer[] nums = positiveSet.toArray(new Integer[positiveSet.size()]); + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + int sum = nums[i] + nums[j]; + if (negativeSet.contains(sum)) { + List oneSum = new ArrayList<>(3); + oneSum.add(positive ? nums[i] : -nums[i]); + oneSum.add(positive ? nums[j] : -nums[j]); + oneSum.add(positive ? -sum : sum); + sumList.add(oneSum); + } + } + } + return sumList; + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/graph/Edge.java b/src/main/java/org/wcong/test/algorithm/graph/Edge.java new file mode 100644 index 0000000..4e996bd --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/graph/Edge.java @@ -0,0 +1,27 @@ +package org.wcong.test.algorithm.graph; + +/** + * Created by wcong on 2017/2/23. + */ +public class Edge { + + private Vertices start; + + private Vertices end; + + public Vertices getStart() { + return start; + } + + public void setStart(Vertices start) { + this.start = start; + } + + public Vertices getEnd() { + return end; + } + + public void setEnd(Vertices end) { + this.end = end; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/graph/Graph.java b/src/main/java/org/wcong/test/algorithm/graph/Graph.java new file mode 100644 index 0000000..896fbf6 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/graph/Graph.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.graph; + +import java.util.List; + +/** + * Created by wcong on 2017/2/23. + */ +public class Graph { + + private int vertices; + + private int edge; + + private List[] adjacencyList; + + + public int getVertices() { + return vertices; + } + + public void setVertices(int vertices) { + this.vertices = vertices; + } + + public int getEdge() { + return edge; + } + + public void setEdge(int edge) { + this.edge = edge; + } + + public List[] getAdjacencyList() { + return adjacencyList; + } + + public void setAdjacencyList(List[] adjacencyList) { + this.adjacencyList = adjacencyList; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/graph/Vertices.java b/src/main/java/org/wcong/test/algorithm/graph/Vertices.java new file mode 100644 index 0000000..6301b98 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/graph/Vertices.java @@ -0,0 +1,18 @@ +package org.wcong.test.algorithm.graph; + +/** + * Created by wcong on 2017/2/23. + */ +public class Vertices { + + private T t; + + + public T getT() { + return t; + } + + public void setT(T t) { + this.t = t; + } +} From 50f44218b8836ab7340cd11516aae517004d333e Mon Sep 17 00:00:00 2001 From: wcong Date: Thu, 23 Mar 2017 19:42:48 +0800 Subject: [PATCH 35/96] add two algorithm --- .../wcong/test/algorithm/ThreeSumClosed.java | 14 +++ .../algorithm/jzoffer/FindInTwoDimension.java | 79 +++++++++++++ .../test/algorithm/jzoffer/ReplaceBlank.java | 37 ++++++ .../wcong/test/algorithm/tree/BinaryTree.java | 108 ++++++++++++++++++ 4 files changed, 238 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java create mode 100644 src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java diff --git a/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java b/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java new file mode 100644 index 0000000..8463cd2 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java @@ -0,0 +1,14 @@ +package org.wcong.test.algorithm; + +/** + * dasdsaadsaasdsasadsdss + * Created by hzwangcong on 2017/3/9. + */ +public class ThreeSumClosed { + + public static void main(String[] args) { + + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java b/src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java new file mode 100644 index 0000000..121cb43 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java @@ -0,0 +1,79 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for array + * in a sorted tow dimension array,which is increasing from left to right,top to bottom. + * is there a target in that array. + * Created by wcong on 2017/3/23. + */ +public class FindInTwoDimension { + + public static void main(String[] args) { + int[][] findMatrix = new int[][]{{1, 4, 7, 10, 13}, {2, 5, 8, 16, 17}, {3, 6, 9, 12, 15}}; + Assert.isTrue(findInTwoDimensionLogN(findMatrix, 5)); + Assert.isTrue(!findInTwoDimensionLogN(findMatrix, 11)); + Assert.isTrue(!findInTwoDimensionLogN(null, 11)); + } + + public static boolean findInDimensionBigON(int[][] matrix, int target) { + if (matrix == null) { + return false; + } + for (int i = 0; i < matrix.length; i++) { + int start = 0; + int end = matrix[i].length; + while (start <= end) { + int middle = start + (end - start) / 2; + if (matrix[i][middle] == target) { + return true; + } else if (matrix[i][middle] < target) { + start = middle + 1; + } else { + end = middle - 1; + } + } + } + return false; + } + + public static boolean findInTwoDimensionLogN(int[][] matrix, int target) { + if (matrix == null || matrix.length <= 0) { + return false; + } + return findInTwoDimensionSub(matrix, 0, matrix[0].length - 1, target); + } + + public static boolean findInTwoDimensionSub(int[][] matrix, int row, int column, int target) { + if (row >= matrix.length) { + return false; + } + int startColumn = 0; + int endColumn = column; + while (startColumn <= endColumn) { + int middle = startColumn + (endColumn - startColumn) / 2; + if (matrix[row][middle] == target) { + return true; + } else if (matrix[row][middle] > target) { + endColumn = middle - 1; + } else { + startColumn = middle + 1; + } + } + int startRow = row; + int endRow = matrix.length - 1; + while (startRow <= endRow) { + int middle = startRow + (endRow - startRow) / 2; + if (matrix[middle][endColumn] == target) { + return true; + } else if (matrix[middle][endColumn] < target) { + startRow = middle + 1; + } else { + endRow = middle - 1; + } + } + return findInTwoDimensionSub(matrix, endRow + 1, endColumn - 1, target); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java new file mode 100644 index 0000000..45119b8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java @@ -0,0 +1,37 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for string + * give a string replace all blank by %20 + * Created by wcong on 2017/3/23. + */ +public class ReplaceBlank { + + public static void main(String[] args) { + Assert.isTrue(replaceString("abs as das ").equals("abs%20as%20%20das%20")); + } + + public static String replaceString(String oldString) { + int length = oldString.length(); + for (int i = 0; i < oldString.length(); i++) { + if (oldString.charAt(i) == ' ') { + length += 2; + } + } + char[] newChar = new char[length]; + int newCharIndex = 0; + for (int i = 0; i < oldString.length(); i++) { + if (oldString.charAt(i) == ' ') { + newChar[newCharIndex++] = '%'; + newChar[newCharIndex++] = '2'; + newChar[newCharIndex++] = '0'; + } else { + newChar[newCharIndex++] = oldString.charAt(i); + } + } + return new String(newChar); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java new file mode 100644 index 0000000..c78b0aa --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java @@ -0,0 +1,108 @@ +package org.wcong.test.algorithm.tree; + +/** + * Created by wcong on 2017/3/17. + */ +public class BinaryTree { + + Node root; + + + public static class Node { + + public Node(int key) { + this.key = key; + } + + int key; + + Node left; + + Node right; + + } + + public Node root() { + return root; + } + + public void addNode(int key) { + if (root == null) { + root = new Node(key); + return; + } + addNodeInternal(key, root); + } + + public void deleteNode(int key) { + if (root == null) { + return; + } + if (root.key == key) { + if (root.right == null) { + if (root.left == null) { + root = null; + } else { + root = root.left; + } + } else { + Node parent = root; + Node replace = root.right; + while (replace.left != null) { + parent = replace; + replace = replace.left; + } + if (parent.left == replace) { + parent.left = null; + } else { + parent.right = replace.right; + } + root.key = replace.key; + } + } else { + + } + } + + + private void deleteNodeInternal(Node parent, Node node, int key) { + if (node == null) { + return; + } + if (node.key == key) { + if (node.right == null && node.left == null) { + if( parent.left == node ){ + parent.left = null; + }else{ + parent.right = null; + } + }else if( node.right == null ){ + + } + } else if (node.key < key) { + deleteNodeInternal(node, node.right, key); + } else { + deleteNodeInternal(node, node.left, key); + } + } + + private void addNodeInternal(int key, Node node) { + if (node.key == key) { + return; + } + if (key < node.key) { + if (node.left == null) { + node.left = new Node(key); + } else { + addNodeInternal(key, node.left); + } + } else { + if (node.right == null) { + node.right = new Node(key); + } else { + addNodeInternal(key, node.right); + } + } + } + +} From 2d29d993122f2a582bab6d3ad6f06d90bd5354a8 Mon Sep 17 00:00:00 2001 From: wcong Date: Fri, 24 Mar 2017 14:20:51 +0800 Subject: [PATCH 36/96] add construct binary tree --- .../jzoffer/ConstructBinaryTree.java | 100 ++++++++++++++++++ .../jzoffer/PrintLinkedListFromBottom.java | 20 ++++ 2 files changed, 120 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java new file mode 100644 index 0000000..49cea52 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java @@ -0,0 +1,100 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +import java.util.Stack; + +/** + * test for tree + * give a binary tree there inorder preorder postorder tree walk, + * build a binary tree by preorder 12473568 and inorder 47215386 out put + * Created by wcong on 2017/3/23. + */ +public class ConstructBinaryTree { + + + public static void main(String[] args) { + Assert.isTrue(constructBinaryTree("12473568", "47215386").preOrderString().equals("12473568")); + } + + static class BinaryTreeNode { + char value; + BinaryTreeNode left; + BinaryTreeNode right; + } + + static class BinaryTree { + BinaryTreeNode root; + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof BinaryTree)) { + return false; + } + return isEqual(root, ((BinaryTree) o).root); + } + + private boolean isEqual(BinaryTreeNode node1, BinaryTreeNode node2) { + if (node1 == null && node2 == null) { + return true; + } + if (node1 != null && node2 != null) { + return node1.value == node2.value && isEqual(node1.left, node2.left) && isEqual(node1.right, node2.right); + } + return false; + } + + public String preOrderString() { + StringBuilder sb = new StringBuilder(12); + Stack tempNodeStack = new Stack<>(); + tempNodeStack.add(root); + while (!tempNodeStack.isEmpty()) { + BinaryTreeNode node = tempNodeStack.pop(); + sb.append(node.value); + if (node.right != null) { + tempNodeStack.push(node.right); + } + if (node.left != null) { + tempNodeStack.push(node.left); + } + } + return sb.toString(); + } + } + + //by preorder 12473568 and inorder 47215386 + static BinaryTree constructBinaryTree(String preOrder, String inOrder) { + if (preOrder == null || inOrder == null || preOrder.length() == 0 || inOrder.length() == 0 || preOrder.length() != inOrder.length()) { + return null; + } + char[] preOrderArray = preOrder.toCharArray(); + char[] inOrderArray = inOrder.toCharArray(); + BinaryTree binaryTree = new BinaryTree(); + binaryTree.root = buildTree(preOrderArray, 0, preOrderArray.length - 1, inOrderArray, 0, inOrderArray.length - 1); + return binaryTree; + } + + private static BinaryTreeNode buildTree(char[] preOrderArray, int preOrderArrayLeft, int preOrderArrayRight, + char[] inOrderArray, int inOrderArrayLeft, int inOrderArrayRight) { + if (preOrderArrayLeft > preOrderArrayRight) { + return null; + } + char inNode = preOrderArray[preOrderArrayLeft]; + BinaryTreeNode node = new BinaryTreeNode(); + node.value = inNode; + int leftIndex = inOrderArrayLeft; + while (leftIndex <= inOrderArrayRight) { + if (inOrderArray[leftIndex] == inNode) { + break; + } + leftIndex += 1; + } + node.left = buildTree(preOrderArray, preOrderArrayLeft + 1, preOrderArrayLeft+leftIndex-inOrderArrayLeft, inOrderArray, inOrderArrayLeft, leftIndex - 1); + node.right = buildTree(preOrderArray, preOrderArrayLeft+leftIndex-inOrderArrayLeft + 1, preOrderArrayRight, inOrderArray, leftIndex + 1, inOrderArrayRight); + return node; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java new file mode 100644 index 0000000..6565006 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java @@ -0,0 +1,20 @@ +package org.wcong.test.algorithm.jzoffer; + +import java.util.List; + +/** + * test for linked list + * give a linked list pring it from bottom + * Created by wcong on 2017/3/23. + */ +public class PrintLinkedListFromBottom { + + public static void main(String[] args) { + + } + + public static void printRecursive(List linkedList) { + + } + +} From bb7e61adf791e2eafd73494f7306fdfc4ff0f9f5 Mon Sep 17 00:00:00 2001 From: wcong Date: Fri, 24 Mar 2017 21:00:28 +0800 Subject: [PATCH 37/96] add some algorithm --- .../test/algorithm/jzoffer/Fibonacci.java | 30 ++++++++ .../jzoffer/MinNumInRotateArray.java | 61 +++++++++++++++++ .../test/algorithm/jzoffer/PowerOfNumber.java | 68 +++++++++++++++++++ .../algorithm/jzoffer/TwoStackForQueue.java | 48 +++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java b/src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java new file mode 100644 index 0000000..603bfc7 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java @@ -0,0 +1,30 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.eclipse.core.runtime.Assert; + +/** + * test for recursive and numbers + * Created by wcong on 2017/3/24. + */ +public class Fibonacci { + + public static void main(String[] args) { + Assert.isTrue(fibonacci(2) == 2); + Assert.isTrue(fibonacci(4) == 5); + Assert.isTrue(fibonacci(6) == 13); + } + + static int fibonacci(int n) { + if (n < 2) { + return 1; + } + int last = 1; + int lastOfLast = 1; + for (int i = 2; i < n; i++) { + int now = last + lastOfLast; + lastOfLast = last; + last = now; + } + return last + lastOfLast; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java new file mode 100644 index 0000000..d9917c5 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java @@ -0,0 +1,61 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +import java.util.Arrays; + +/** + * test for sort and search + * give a sorted array and rotate some num,find the min num in it + * Created by wcong on 2017/3/24. + */ +public class MinNumInRotateArray { + + public static void main(String[] args) { + Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 2), new int[]{6, 7, 1, 2, 3, 4, 5})); + Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 5), new int[]{3, 4, 5, 6, 7, 1, 2})); + Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 4), new int[]{5, 6, 7, 8, 1, 2, 3, 4})); + Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 4))==1); + Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 5))==1); + Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 2))==1); + } + + // example 12345678 34567812 + private static int[] rotateArray(int[] array, int rotate) { + if (array == null || array.length <= 1 || rotate <= 0) { + return array; + } + int n = array.length; + int start = 0; + while (n > 0 && (rotate = rotate % n) > 0) { + for (int i = 0; i < rotate; i++) { + int index = start + i; + int swapIndex = n - rotate + i + start; + int temp = array[index]; + array[index] = array[swapIndex]; + array[swapIndex] = temp; + } + start += rotate; + n -= rotate; + } + return array; + } + + private static int findMinNumForRotateArray(int[] array) { + if (array == null || array.length == 0) { + throw new RuntimeException("wrong array"); + } + int first = array[0]; + int left = 0, right = array.length - 1; + while (left <= right) { + int middle = left + (right - left) / 2; + if (array[middle] > first) { + left = middle + 1; + } else { + right = middle - 1; + } + } + return array[left]; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java new file mode 100644 index 0000000..e987413 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java @@ -0,0 +1,68 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for exception and number operation + * give a base number and a exponent return of power of them + * Created by wcong on 2017/3/24. + */ +public class PowerOfNumber { + + public static void main(String[] args) { + + } + + // + public static double powerSlow(double base, int exponent) { + if (base == 0 && exponent <= 0) { + throw new RuntimeException("no meaning"); + } + + if (exponent == 0) return 1; + boolean positive = exponent >= 0; + exponent = positive ? exponent : -exponent; + double result = base; + for (int i = 1; i < exponent; i++) { + result *= base; + } + if (!positive) { + result = 1.0 / result; + } + return result; + } + + public static double powerLogN(double base, int exponent) { + if (base == 0 && exponent <= 0) { + throw new RuntimeException("no meaning"); + } + if (exponent == 0) return 1; + boolean positive = exponent >= 0; + double result = 1.0; + while (exponent > 0) { + result = power(base, exponent >> 1); + result *= result; + if ((exponent & 1) > 0) { + result *= base; + } + } + if (!positive) { + result = 1.0 / result; + } + return result; + } + + private static double power(double base, int exponent) { + double result = 1.0; + if (exponent <= 0) { + return result; + } + while (exponent > 0) { + result = power(base, exponent >> 1); + result *= result; + if ((exponent & 1) > 0) { + result *= base; + } + } + return result; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java new file mode 100644 index 0000000..96e5e9b --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java @@ -0,0 +1,48 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +import java.util.Stack; + +/** + * test for stack and queue + * implement a queue bu two stack + * Created by wcong on 2017/3/24. + */ +public class TwoStackForQueue { + + + public static void main(String[] args) { + StackQueue stackQueue = new StackQueue(); + stackQueue.push(1); + stackQueue.push(2); + stackQueue.push(3); + stackQueue.push(4); + Assert.isTrue(stackQueue.pop() == 1); + Assert.isTrue(stackQueue.pop() == 2); + Assert.isTrue(stackQueue.pop() == 3); + Assert.isTrue(stackQueue.pop() == 4); + } + + + public static class StackQueue { + + private Stack in = new Stack<>(); + + private Stack out = new Stack<>(); + + public void push(int num) { + in.push(num); + } + + public int pop() { + if (out.isEmpty()) { + while (!in.isEmpty()) { + out.push(in.pop()); + } + } + return out.pop(); + } + } + +} From 4a9241109a5e58336597740de08dd48194db7023 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 13:43:57 +0800 Subject: [PATCH 38/96] add count 1 binary --- .../test/algorithm/jzoffer/Count1InInt.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java b/src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java new file mode 100644 index 0000000..04d43e4 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java @@ -0,0 +1,43 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for binary operate and or xor and smart move to recursive + * >> remain the sign bit,>>> ignore the sign bit + * + * @author wcong + * @since 2017/3/26 + */ +public class Count1InInt { + + public static void main(String[] args) { + Assert.isTrue(count1Slow(0xFFFF) == count1Smart(0xFFFF)); + Assert.isTrue(count1Slow(0x4444) == count1Smart(0x4444)); + Assert.isTrue(count1Slow(0x3214) == count1Smart(0x3214)); + Assert.isTrue(count1Slow(0x10) == count1Smart(0x10)); + Assert.isTrue(count1Slow(0x1111) == count1Smart(0x1111)); + } + + public static int count1Slow(int num) { + int count = 0; + while (num != 0) { + if ((num & 1) != 0) { + count += 1; + } + num = num >> 1; + } + return count; + } + + public static int count1Smart(int num) { + num = num < 0 ? -num : num; + int count = 0; + while (num > 0) { + count += 1; + num = num & (num - 1); + } + return count; + } + +} From fea375aba4cd07d3e3659494c4193da6c0181c6f Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 13:52:42 +0800 Subject: [PATCH 39/96] add power of numbers --- .../test/algorithm/jzoffer/PowerOfNumber.java | 104 +++++++++--------- .../test/pattern/creational/Multition.java | 34 ++++++ .../org/wcong/test/pattern/package-info.java | 2 + 3 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 src/main/java/org/wcong/test/pattern/creational/Multition.java create mode 100644 src/main/java/org/wcong/test/pattern/package-info.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java index e987413..467bed9 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java @@ -1,5 +1,7 @@ package org.wcong.test.algorithm.jzoffer; +import org.springframework.util.Assert; + /** * test for exception and number operation * give a base number and a exponent return of power of them @@ -7,62 +9,58 @@ */ public class PowerOfNumber { - public static void main(String[] args) { - - } + public static void main(String[] args) { + Assert.isTrue(powerSlow(3, 9) == powerLogN(3, 9)); + Assert.isTrue(powerSlow(-3, -9) == powerLogN(-3, -9)); + Assert.isTrue(powerSlow(0, 0) == powerLogN(0, 0)); + } - // - public static double powerSlow(double base, int exponent) { - if (base == 0 && exponent <= 0) { - throw new RuntimeException("no meaning"); - } + // + public static double powerSlow(double base, int exponent) { + if (base == 0 && exponent <= 0) { + throw new RuntimeException("no meaning"); + } - if (exponent == 0) return 1; - boolean positive = exponent >= 0; - exponent = positive ? exponent : -exponent; - double result = base; - for (int i = 1; i < exponent; i++) { - result *= base; - } - if (!positive) { - result = 1.0 / result; - } - return result; - } + if (exponent == 0) + return 1; + boolean positive = exponent >= 0; + exponent = positive ? exponent : -exponent; + double result = base; + for (int i = 1; i < exponent; i++) { + result *= base; + } + if (!positive) { + result = 1.0 / result; + } + return result; + } - public static double powerLogN(double base, int exponent) { - if (base == 0 && exponent <= 0) { - throw new RuntimeException("no meaning"); - } - if (exponent == 0) return 1; - boolean positive = exponent >= 0; - double result = 1.0; - while (exponent > 0) { - result = power(base, exponent >> 1); - result *= result; - if ((exponent & 1) > 0) { - result *= base; - } - } - if (!positive) { - result = 1.0 / result; - } - return result; - } + public static double powerLogN(double base, int exponent) { + if (base == 0 && exponent <= 0) { + throw new RuntimeException("no meaning"); + } + if (exponent == 0) + return 1; + boolean positive = exponent >= 0; + exponent = positive ? exponent : -exponent; + double result = power(base, exponent); + if (!positive) { + result = 1.0 / result; + } + return result; + } - private static double power(double base, int exponent) { - double result = 1.0; - if (exponent <= 0) { - return result; - } - while (exponent > 0) { - result = power(base, exponent >> 1); - result *= result; - if ((exponent & 1) > 0) { - result *= base; - } - } - return result; - } + private static double power(double base, int exponent) { + double result = 1.0; + if (exponent <= 0) { + return result; + } + result = power(base, exponent >> 1); + result *= result; + if ((exponent & 1) > 0) { + result *= base; + } + return result; + } } diff --git a/src/main/java/org/wcong/test/pattern/creational/Multition.java b/src/main/java/org/wcong/test/pattern/creational/Multition.java new file mode 100644 index 0000000..97ff47b --- /dev/null +++ b/src/main/java/org/wcong/test/pattern/creational/Multition.java @@ -0,0 +1,34 @@ +package org.wcong.test.pattern.creational; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author wcong + * @since 2017/1/2 + */ +public class Multition { + + public static void main(String[] args){ + int[] nums = {1,3}; + System.out.println(index(0,nums.length,nums,0)); + } + + private static int index(int start,int end,int[] nums,int target){ + if( start == end ){ + if( nums[start] == target ){ + return start; + }else if( nums[start] > target ){ + return start; + }else{ + return start +1; + } + } + int middle = start + (end - start)/2; + if( nums[middle] == target ){ + return middle; + } + return index(start+1>middle?middle:start+1,end -1,nums,target); + } + +} diff --git a/src/main/java/org/wcong/test/pattern/package-info.java b/src/main/java/org/wcong/test/pattern/package-info.java new file mode 100644 index 0000000..2478af4 --- /dev/null +++ b/src/main/java/org/wcong/test/pattern/package-info.java @@ -0,0 +1,2 @@ +package org.wcong.test.pattern; +// about java pattern examples \ No newline at end of file From e0ed8fe94878d78e496c11afe1e316dacd12e890 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 14:27:27 +0800 Subject: [PATCH 40/96] add PrintNumberOfN --- .../algorithm/jzoffer/PrintNumberOfN.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java new file mode 100644 index 0000000..f9680a9 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java @@ -0,0 +1,43 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test number limit boundary + * give a number n print all the numbers of decimal + * + * @author wcong + * @since 2017/3/26 + */ +public class PrintNumberOfN { + + public static void main(String[] args) { + printNumberOfN(3); + } + + public static void printNumberOfN(int n) { + char[] number = new char[n]; + printInteger(number, 0, n - 1); + } + + private static void printInteger(char[] number, int index, int n) { + if (index > n) { + int startIndex = 0; + while (startIndex < n) { + if (number[startIndex] == 48) { + startIndex += 1; + } else { + break; + } + } + while (startIndex <= n) { + System.out.print(number[startIndex++]); + } + System.out.print("\n"); + return; + } + for (int j = 48; j < 58; j++) { + number[index] = (char) j; + printInteger(number, index + 1, n); + } + } + +} From 971f59de55873643c512f1bdbd0cb35c4edfab39 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 14:38:53 +0800 Subject: [PATCH 41/96] add DeleteNodeInO1 --- .../algorithm/jzoffer/DeleteNodeInO1.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java b/src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java new file mode 100644 index 0000000..630966b --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java @@ -0,0 +1,42 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for linked list basic operate,search,add,delete + * give a linked list root and delete node,delete this node in O(1) time + * + * @author wcong + * @since 2017/3/26 + */ +public class DeleteNodeInO1 { + + public static void main(String[] args) { + } + + public static class LinkedNode { + int value; + + LinkedNode next; + } + + public static LinkedNode deleteInO1(LinkedNode root, LinkedNode delete) { + if (root == null || delete == null) { + return null; + } + if (delete.next != null) { + delete.value = delete.next.value; + delete.next = delete.next.next; + } else if (root == delete) { + return null; + } else { + LinkedNode parent = root; + while (parent.next != delete) { + parent = parent.next; + } + parent.next = null; + } + return root; + } + +} From dab31fe01f078ae083e24856c42b627d844b0a85 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 15:02:53 +0800 Subject: [PATCH 42/96] add ReArrangeOddAndEven --- .../jzoffer/ReArrangeOddAndEven.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java new file mode 100644 index 0000000..c1c19f7 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java @@ -0,0 +1,45 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +import java.util.Arrays; + +/** + * test for array and odd and even and two pointers + * give an array of integer rearrange odd number to left and even number to left + * + * @author wcong + * @since 2017/3/26 + */ +public class ReArrangeOddAndEven { + + public static void main(String[] args) { + Assert.isTrue( + Arrays.equals(rearrange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }), new int[] { 1, 7, 3, 5, 4, 6, 2, 8 })); + } + + public static int[] rearrange(int[] array) { + if (array == null || array.length == 0) { + return array; + } + int leftEvenIndex = 0; + int rightOddIndex = array.length - 1; + while (leftEvenIndex < rightOddIndex) { + if ((array[leftEvenIndex] & 1) != 0) { + leftEvenIndex += 1; + continue; + } + if ((array[rightOddIndex] & 1) == 0) { + rightOddIndex -= 1; + continue; + } + int temp = array[leftEvenIndex]; + array[leftEvenIndex] = array[rightOddIndex]; + array[rightOddIndex] = temp; + leftEvenIndex += 1; + rightOddIndex -= 1; + } + return array; + } + +} From 0bc01695660f58e3caa386a849f8e02e6dc826db Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 15:43:17 +0800 Subject: [PATCH 43/96] add BuildLinkedList --- .../jzoffer/LastKNodeInLinkedList.java | 39 +++++++++++++++++++ .../jzoffer/util/BuildLinkedList.java | 23 +++++++++++ .../algorithm/jzoffer/util/LinkedList.java | 11 ++++++ .../jzoffer/util/LinkedListNode.java | 13 +++++++ 4 files changed, 86 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java new file mode 100644 index 0000000..cd9e40c --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java @@ -0,0 +1,39 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; +import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedListNode; + +/** + * test for linked list and exceptions and continue thinking and two pointers + * + * @author wcong + * @since 2017/3/26 + */ +public class LastKNodeInLinkedList { + + public static void main(String[] args) { + LinkedList one = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 5 }); + Assert.isTrue(lastKNode(one, 6) == null); + Assert.isTrue(lastKNode(one, 3).value == 3); + } + + public static LinkedListNode lastKNode(LinkedList linkedList, int k) { + if (linkedList == null || linkedList.root == null || k < 1) { + return null; + } + LinkedListNode lastKNode = linkedList.root; + int count = 1; + LinkedListNode node = linkedList.root; + while (node.next != null) { + count += 1; + node = node.next; + if (count > k) { + lastKNode = lastKNode.next; + } + } + return count < k ? null : lastKNode; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java new file mode 100644 index 0000000..df220a9 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java @@ -0,0 +1,23 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class BuildLinkedList { + + public static LinkedList makeOne(int[] array) { + LinkedListNode root = new LinkedListNode(); + LinkedList linkedList = new LinkedList(); + linkedList.root = root; + root.value = array[0]; + LinkedListNode parent = root; + for (int i = 1; i < array.length; i++) { + LinkedListNode node = new LinkedListNode(); + node.value = array[i]; + parent.next = node; + parent = node; + } + return linkedList; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java new file mode 100644 index 0000000..1cfb9d1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java @@ -0,0 +1,11 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class LinkedList { + + public LinkedListNode root; + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java new file mode 100644 index 0000000..e4df7df --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java @@ -0,0 +1,13 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class LinkedListNode { + + public int value; + + public LinkedListNode next; + +} From c75e3a95c04aa69081fbc5c43aba7b610560e621 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 16:23:41 +0800 Subject: [PATCH 44/96] add ReversLinkedList --- .../algorithm/jzoffer/ReversLinkedList.java | 40 +++++++++++++++++++ .../algorithm/jzoffer/util/LinkedList.java | 21 ++++++++++ .../jzoffer/util/LinkedListNode.java | 4 ++ 3 files changed, 65 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java new file mode 100644 index 0000000..98e5d7a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; +import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedListNode; + +/** + * test for linked list + * + * @author wcong + * @since 2017/3/26 + */ +public class ReversLinkedList { + + public static void main(String[] args) { + LinkedList list = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 5, 6, 7 }); + LinkedList reverseList = BuildLinkedList.makeOne(new int[] { 7, 6, 5, 4, 3, 2, 1 }); + Assert.isTrue(reverse(list).equal(reverseList)); + } + + public static LinkedList reverse(LinkedList linkedList) { + if (linkedList == null || linkedList.root == null) { + return linkedList; + } + LinkedListNode before = null; + LinkedListNode node = linkedList.root; + LinkedListNode next = node.next; + node.next = null; + while (next != null) { + before = node; + node = next; + next = next.next; + node.next = before; + } + linkedList.root = node; + return linkedList; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java index 1cfb9d1..d1bfc2a 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java @@ -8,4 +8,25 @@ public class LinkedList { public LinkedListNode root; + public boolean equal(LinkedList other) { + if (other == null) { + return false; + } + LinkedListNode otherNode = other.root; + LinkedListNode thisNode = root; + while (true) { + if ((otherNode == null && thisNode == null) || (otherNode != null && thisNode != null + && thisNode.value == otherNode.value)) { + if (otherNode == null) { + break; + } + otherNode = otherNode.next; + thisNode = thisNode.next; + } else { + return false; + } + } + return true; + } + } diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java index e4df7df..aa87b1a 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java @@ -10,4 +10,8 @@ public class LinkedListNode { public LinkedListNode next; + public String toString() { + return String.valueOf(value); + } + } From b53000213a11273ab6c559482366b86cbf185aae Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 26 Mar 2017 17:02:11 +0800 Subject: [PATCH 45/96] add MergeTwoSortedLinkedList --- .../jzoffer/MergeTwoSortedLinkedList.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java new file mode 100644 index 0000000..221f38d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java @@ -0,0 +1,53 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; +import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedListNode; + +/** + * test linked list and merge + * + * @author wcong + * @since 2017/3/26 + */ +public class MergeTwoSortedLinkedList { + + public static void main(String[] args) { + LinkedList list1 = BuildLinkedList.makeOne(new int[] { 1, 3, 4, 5, 6 }); + LinkedList list2 = BuildLinkedList.makeOne(new int[] { 2, 4, 7, 8, 9 }); + LinkedList merge = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 4, 5, 6, 7, 8, 9 }); + Assert.isTrue(mergeSortedList(list1, list2).equal(merge)); + } + + public static LinkedList mergeSortedList(LinkedList list1, LinkedList list2) { + if (list1 == null || list1.root == null) { + return list2; + } + if (list2 == null || list2.root == null) { + return list1; + } + LinkedListNode node1 = list1.root; + LinkedListNode node2 = list2.root; + LinkedList root = node1.value > node2.value ? list2 : list1; + while (node1 != null && node2 != null) { + if (node1.value < node2.value) { + while (node1.next != null && node1.next.value < node2.value) { + node1 = node1.next; + } + LinkedListNode temp = node1.next; + node1.next = node2; + node1 = temp; + } else if (node1.value >= node2.value) { + while (node2.next != null && node2.next.value <= node1.value) { + node2 = node2.next; + } + LinkedListNode temp = node2.next; + node2.next = node1; + node2 = temp; + } + } + return root; + } + +} From 6398e3482ed92629630606c17560bb9f2dbe440d Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 16:45:23 +0800 Subject: [PATCH 46/96] add dynamic programming --- .../leetcode/dp/UniqueBinarySearchTree.java | 41 +++++++++++++++ .../test/algorithm/leetcode/dp/WordBreak.java | 50 +++++++++++++++++++ .../test/algorithm/leetcode/package-info.java | 1 + 3 files changed, 92 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/package-info.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java new file mode 100644 index 0000000..a0918d3 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.leetcode.dp; + +/** + * test for binary search tree and dynamic programing + *

+ * // Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + *

+ * // For example, + * // Given n = 3, there are a total of 5 unique BST's. + *

+ * // 1 3 3 2 1 + * // \ / / / \ \ + * // 3 2 1 1 3 2 + * // / / \ \ + * // 2 1 2 3 + * Created by wcong on 2017/3/27. + */ +public class UniqueBinarySearchTree { + + public static void main(String[] args) { + + } + + + public static int binarySearchTree(int n) { + if (n <= 0) { + return 0; + } + int[] rangeNum = new int[n]; + rangeNum[0] = 1; + rangeNum[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= i; j++) { + rangeNum[i] += rangeNum[j - 1] * rangeNum[j - i]; + } + } + return rangeNum[n]; + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java new file mode 100644 index 0000000..6ee6eee --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java @@ -0,0 +1,50 @@ +package org.wcong.test.algorithm.leetcode.dp; + +/** + * test for dynamic programming + *

+ * // Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, + * determine if s can be segmented into a space-separated sequence of one or more dictionary words. + * You may assume the dictionary does not contain duplicate words. + *

+ * // For example, given + * // s = "leetcode", + * // dict = ["leet", "code"]. + *

+ * // Return true because "leetcode" can be segmented as "leet code". + * Created by wcong on 2017/3/27. + */ +public class WordBreak { + + public static void main(String[] args) { + + } + + // suppose it has none blank char + public static boolean wordBreak(String s, String[] dict) { + if (dict == null || dict.length == 0 || s == null || s.length() == 0) { + return false; + } + boolean[] result = new boolean[s.length()]; + result[0] = true; + for (int i = 0; i < s.length(); i++) { + for (int j = i; j >= 0; j--) { + if (isInDict(s.substring(j, i + 1), dict) && result[j]) { + result[i + 1] = true; + break; + } + } + } + return result[s.length()]; + } + + + private static boolean isInDict(String s, String[] dict) { + for (String word : dict) { + if (word.equals(s)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java b/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java new file mode 100644 index 0000000..3d36c64 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java @@ -0,0 +1 @@ +//for leetcode \ No newline at end of file From d0438aebab71769f136f47bd8a55962902cc5a04 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 17:37:39 +0800 Subject: [PATCH 47/96] add RegularExpressionMatching --- .../dp/RegularExpressionMatching.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java new file mode 100644 index 0000000..b9ac417 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java @@ -0,0 +1,49 @@ +package org.wcong.test.algorithm.leetcode.dp; + +/** + * test for dynamic programming and string matching + *

+ * Implement regular expression matching with support for '.' and '*'. + * '.' Matches any single character. + * '*' Matches zero or more of the preceding element. + * The matching should cover the entire input string (not partial). + * The function prototype should be: + * bool isMatch(const char *s, const char *p) + * Created by wcong on 2017/3/27. + */ +public class RegularExpressionMatching { + + public static void main(String[] args) { + + } + + public static boolean isMatch(String s, String pattern) { + if (s == null || s.isEmpty() || pattern == null || pattern.isEmpty()) { + return false; + } + boolean[][] result = new boolean[s.length() + 1][pattern.length() + 1]; + result[0][0] = true; + for (int i = 0; i < pattern.length(); i++) { + if (pattern.charAt(i) == '*' && result[0][i - 1]) { + result[0][i + 1] = true; + } + } + for (int i = 0; i < s.length(); i++) { + for (int j = 0; j < pattern.length(); j++) { + if (pattern.charAt(j) == '.') { + result[i + 1][j + 1] = result[i][j]; + } else if (pattern.charAt(j) != '*') { + result[i + 1][j + 1] = result[i][j] && (s.charAt(i) == pattern.charAt(j)); + } else { + if (pattern.charAt(j - 1) != s.charAt(i) && pattern.charAt(j - 1) != '.') { + result[i + 1][j + 1] = result[i + 1][j - 1]; + } else { + result[i + 1][j + 1] = (result[i + 1][j] || result[i][j + 1] || result[i + 1][j - 1]); + } + } + } + } + return result[s.length()][pattern.length()]; + } + +} From bd512f0e099bb8b1425f99a93b7bece303444a9e Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 18:55:24 +0800 Subject: [PATCH 48/96] add algorithm --- .../jzoffer/BinaryTreePostOrderWalkRule.java | 10 +++++ .../jzoffer/ChangeBinaryTreeToDQueue.java | 9 ++++ .../jzoffer/ComplexListNodeCopy.java | 37 ++++++++++++++++ .../test/algorithm/jzoffer/IsSubTree.java | 43 +++++++++++++++++++ .../algorithm/jzoffer/MirrorOfBinaryTree.java | 36 ++++++++++++++++ .../test/algorithm/jzoffer/O1MinStack.java | 40 +++++++++++++++++ .../jzoffer/PrintBinaryTreeTopDown.java | 39 +++++++++++++++++ .../algorithm/jzoffer/StackPushPopRule.java | 10 +++++ .../algorithm/jzoffer/util/BuildTree.java | 35 +++++++++++++++ .../jzoffer/util/ComplexListNode.java | 17 ++++++++ .../test/algorithm/jzoffer/util/Tree.java | 11 +++++ .../test/algorithm/jzoffer/util/TreeNode.java | 15 +++++++ 12 files changed, 302 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java new file mode 100644 index 0000000..701eac9 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java @@ -0,0 +1,10 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * TODO + * + * @author wcong + * @since 2017/3/26 + */ +public class BinaryTreePostOrderWalkRule { +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java new file mode 100644 index 0000000..e52910f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java @@ -0,0 +1,9 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for tree and dqueue TODO + * @author wcong + * @since 2017/3/26 + */ +public class ChangeBinaryTreeToDQueue { +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java new file mode 100644 index 0000000..ee4f24d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java @@ -0,0 +1,37 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.wcong.test.algorithm.jzoffer.util.ComplexListNode; + +/** + * test for linked list TODO + * + * @author wcong + * @since 2017/3/26 + */ +public class ComplexListNodeCopy { + + public static ComplexListNode copyComplexList(ComplexListNode head) { + if (head == null) { + return null; + } + ComplexListNode node = head; + while (node != null) { + ComplexListNode copy = new ComplexListNode(); + copy.value = node.value; + copy.next = node.next; + node.next = copy; + node = copy.next; + } + node = head; + while (node != null) { + ComplexListNode copy = node.next; + if (node.other != null) { + copy.other = node.other.next; + } + node = copy.next; + } + node = head; + return node; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java new file mode 100644 index 0000000..a42c024 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java @@ -0,0 +1,43 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.wcong.test.algorithm.jzoffer.util.Tree; +import org.wcong.test.algorithm.jzoffer.util.TreeNode; + +/** + * test for tree + *

+ * give tow tree,judge is one tree is other sub tree + * + * @author wcong + * @since 2017/3/26 + */ +public class IsSubTree { + + public static void main(String[] args) { + + } + + public static boolean isSubTree(Tree tree, Tree subTree) { + if (tree == null || tree.root == null || subTree == null || subTree.root == null) { + return false; + } + TreeNode subNode = subTree.root; + TreeNode fromNode = findSameNode(tree.root, subNode); + return false; + } + + public static TreeNode findSameNode(TreeNode node, TreeNode example) { + if (node == null || example == null) { + return null; + } + if (node.value == example.value) { + return node; + } + TreeNode leftResult = findSameNode(node.left, example); + if (leftResult != null) { + return leftResult; + } + return findSameNode(node.right, example); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java new file mode 100644 index 0000000..e98fbd5 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java @@ -0,0 +1,36 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.wcong.test.algorithm.jzoffer.util.Tree; +import org.wcong.test.algorithm.jzoffer.util.TreeNode; + +/** + * test for binary tree + *

+ * give a binary tree return a mirror of it,left to right and right to left + * + * @author wcong + * @since 2017/3/26 + */ +public class MirrorOfBinaryTree { + + public static void main(String[] args) { + + } + + public static void mirrorOfBinaryTree(Tree tree) { + mirrorOfNode(tree.root); + } + + private static void mirrorOfNode(TreeNode treeNode) { + if (treeNode == null) { + return; + } + TreeNode temp = treeNode.left; + treeNode.left = treeNode.right; + treeNode.right = temp; + mirrorOfNode(treeNode.left); + mirrorOfNode(treeNode.right); + + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java b/src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java new file mode 100644 index 0000000..b1432d5 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.jzoffer; + +import java.util.Stack; + +/** + * test for stack and its operation + * implement a push pop and min all O(1) time use + * + * @author wcong + * @since 2017/3/26 + */ +public class O1MinStack { + + public static class MinO1Stack { + + private Stack normal; + + private Stack min; + + public void push(int num) { + normal.push(num); + if (min.isEmpty() || min.lastElement() > num) { + min.push(num); + } else { + min.push(min.lastElement()); + } + } + + public int pop() { + min.pop(); + return normal.pop(); + } + + public int min() { + return min.lastElement(); + } + + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java new file mode 100644 index 0000000..39761f7 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java @@ -0,0 +1,39 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.wcong.test.algorithm.jzoffer.util.Tree; +import org.wcong.test.algorithm.jzoffer.util.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * test for binary tree + * + * @author wcong + * @since 2017/3/26 + */ +public class PrintBinaryTreeTopDown { + + public static void main(String[] args) { + + } + + public static void printTreeTopDown(Tree tree) { + if (tree == null || tree.root == null) { + return; + } + Queue treeNodeQueue = new LinkedList<>(); + treeNodeQueue.add(tree.root); + while (!treeNodeQueue.isEmpty()) { + TreeNode node = treeNodeQueue.poll(); + System.out.println(node.value); + if (node.left != null) { + treeNodeQueue.add(node.left); + } + if (node.right != null) { + treeNodeQueue.add(node.right); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java new file mode 100644 index 0000000..f6c5b96 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java @@ -0,0 +1,10 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * TODO + * + * @author wcong + * @since 2017/3/26 + */ +public class StackPushPopRule { +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java new file mode 100644 index 0000000..3a49d50 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java @@ -0,0 +1,35 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class BuildTree { + + public static Tree buildOne(int[] array) { + Tree tree = new Tree(); + TreeNode treeNode = new TreeNode(); + treeNode.value = array[0]; + tree.root = treeNode; + buildTree(treeNode, array, 0); + return tree; + } + + private static void buildTree(TreeNode treeNode, int[] array, int h) { + int leftNode = h * 2 + 1; + if (leftNode < array.length) { + TreeNode left = new TreeNode(); + left.value = array[leftNode]; + treeNode.left = left; + buildTree(left, array, h + 1); + } + int rightNode = h * 2 + 2; + if (rightNode < array.length) { + TreeNode right = new TreeNode(); + right.value = array[rightNode]; + treeNode.right = right; + buildTree(right, array, h + 1); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java new file mode 100644 index 0000000..a3a19d1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java @@ -0,0 +1,17 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class ComplexListNode { + public int value; + + public ComplexListNode next; + + public ComplexListNode other; + + public String toString() { + return String.valueOf(value); + } +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java new file mode 100644 index 0000000..45ffe7b --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java @@ -0,0 +1,11 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class Tree { + + public TreeNode root; + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java new file mode 100644 index 0000000..00a12dc --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java @@ -0,0 +1,15 @@ +package org.wcong.test.algorithm.jzoffer.util; + +/** + * @author wcong + * @since 2017/3/26 + */ +public class TreeNode { + + public int value; + + public TreeNode left; + + public TreeNode right; + +} From 7e133d1d1e76fc38a6071ceafe1f5b0113df1bac Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 19:35:05 +0800 Subject: [PATCH 49/96] add StackPushPopRule --- .../algorithm/jzoffer/StackPushPopRule.java | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java index f6c5b96..4f71cfc 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java @@ -1,10 +1,49 @@ package org.wcong.test.algorithm.jzoffer; +import org.springframework.util.Assert; + /** - * TODO + * test for stack operation + * give two array of integer,first is the order of push,judge second is the one of the order of pop + * for example push array 1,2,3,4,5 and pop order 4,5,3,2,1 is correct but 4,3,5,1,2 is not * * @author wcong * @since 2017/3/26 */ public class StackPushPopRule { + + public static void main(String[] args) { + Assert.isTrue(isPopToPush(new int[]{1, 2, 3, 4, 5}, new int[]{4, 5, 3, 2, 1})); + Assert.isTrue(!isPopToPush(new int[]{1, 2, 3, 4, 5}, new int[]{4, 3, 5, 1, 2})); + } + + public static boolean isPopToPush(int[] pushArray, int[] popArray) { + if (pushArray == null || popArray == null) { + return false; + } + int index = -1; + for (int push : pushArray) { + index += 1; + if (push == popArray[0]) { + break; + } + } + if (index < 0) { + return false; + } + int left = index - 1, right = index + 1; + for (int i = 1; i < popArray.length; i++) { + if (left >= 0 && pushArray[left] == popArray[i]) { + left -= 1; + continue; + } + if (right < pushArray.length && pushArray[right] == popArray[i]) { + right += 1; + continue; + } + return false; + } + return true; + } + } From bf35458f083e35e39066d8d969a5f53fc65edb33 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 19:54:55 +0800 Subject: [PATCH 50/96] add BinaryTreePostOrderWalkRule --- .../jzoffer/BinaryTreePostOrderWalkRule.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java index 701eac9..8cafc0f 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java @@ -1,10 +1,46 @@ package org.wcong.test.algorithm.jzoffer; +import org.springframework.util.Assert; + /** - * TODO + * test for binary tree post-order walk analysis + * give a array of integer judge is binary search tree post-order walk + * for example 5,7,6,9,11,10,8 is true,7,4,6,5 is not * * @author wcong * @since 2017/3/26 */ public class BinaryTreePostOrderWalkRule { + + public static void main(String[] args) { + Assert.isTrue(isBinarySearchTree(new int[]{5, 7, 6, 9, 11, 10, 8})); + Assert.isTrue(!isBinarySearchTree(new int[]{7, 4, 6, 5})); + } + + public static boolean isBinarySearchTree(int[] array) { + if (array == null || array.length == 0) { + return false; + } + return isBinarySearchTree(array, 0, array.length - 1); + } + + private static boolean isBinarySearchTree(int[] array, int start, int end) { + if (start > end || start < 0 || end > array.length) { + return true; + } + int middle = array[end]; + int leftEnd = start; + for (; leftEnd < end; leftEnd++) { + if (array[leftEnd] >= middle) { + break; + } + } + leftEnd -= 1; + for (int i = leftEnd + 1; i < end; i++) { + if (array[i] < middle) { + return false; + } + } + return isBinarySearchTree(array, start, leftEnd) && isBinarySearchTree(array, leftEnd + 1, end - 1); + } } From 0d409ef618569ff90c58cd7195e2c62ac22b5b5d Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 20:56:07 +0800 Subject: [PATCH 51/96] add ComplexListNodeCopy --- .../jzoffer/ChangeBinaryTreeToDQueue.java | 34 +++++++++++ .../jzoffer/ComplexListNodeCopy.java | 58 +++++++++++-------- .../algorithm/jzoffer/util/BuildTree.java | 4 +- 3 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java index e52910f..3306905 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java @@ -1,9 +1,43 @@ package org.wcong.test.algorithm.jzoffer; +import org.wcong.test.algorithm.jzoffer.util.BuildTree; +import org.wcong.test.algorithm.jzoffer.util.Tree; +import org.wcong.test.algorithm.jzoffer.util.TreeNode; + /** * test for tree and dqueue TODO + * give a binary tree change it to dqueue + * * @author wcong * @since 2017/3/26 */ public class ChangeBinaryTreeToDQueue { + + + public static void main(String[] args) { + changeToDQueue(BuildTree.buildOne(new int[]{4, 2, 6, 1, 3, 5, 7})); + } + + public static TreeNode changeToDQueue(Tree tree) { + return changeToDQueue(tree.root); + } + + private static TreeNode changeToDQueue(TreeNode treeNode) { + if (treeNode.left == null && treeNode.right == null) { + return treeNode; + } + if (treeNode.left != null) { + TreeNode node = changeToDQueue(treeNode.left); + node.right = treeNode; + treeNode.left = node; + } + TreeNode right = treeNode; + if (treeNode.right != null) { + TreeNode node = changeToDQueue(treeNode.right); + treeNode.right = node; + node.left = treeNode; + } + return right; + } + } diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java index ee4f24d..ebeca0c 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java @@ -3,35 +3,45 @@ import org.wcong.test.algorithm.jzoffer.util.ComplexListNode; /** - * test for linked list TODO + * test for linked list + * give a complex linked list copy it * * @author wcong * @since 2017/3/26 */ public class ComplexListNodeCopy { - public static ComplexListNode copyComplexList(ComplexListNode head) { - if (head == null) { - return null; - } - ComplexListNode node = head; - while (node != null) { - ComplexListNode copy = new ComplexListNode(); - copy.value = node.value; - copy.next = node.next; - node.next = copy; - node = copy.next; - } - node = head; - while (node != null) { - ComplexListNode copy = node.next; - if (node.other != null) { - copy.other = node.other.next; - } - node = copy.next; - } - node = head; - return node; - } + public static ComplexListNode copyComplexList(ComplexListNode head) { + if (head == null) { + return null; + } + ComplexListNode node = head; + while (node != null) { + ComplexListNode copy = new ComplexListNode(); + copy.value = node.value; + copy.next = node.next; + node.next = copy; + node = copy.next; + } + node = head; + while (node != null) { + ComplexListNode copy = node.next; + if (node.other != null) { + copy.other = node.other.next; + } + node = copy.next; + } + node = head; + ComplexListNode root = head.next; + while (node != null) { + ComplexListNode copy = node.next; + node.next = copy.next; + node = copy.next; + if( copy.next != null ) { + copy.next = copy.next.next; + } + } + return root; + } } diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java index 3a49d50..c305073 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java @@ -21,14 +21,14 @@ private static void buildTree(TreeNode treeNode, int[] array, int h) { TreeNode left = new TreeNode(); left.value = array[leftNode]; treeNode.left = left; - buildTree(left, array, h + 1); + buildTree(left, array, leftNode); } int rightNode = h * 2 + 2; if (rightNode < array.length) { TreeNode right = new TreeNode(); right.value = array[rightNode]; treeNode.right = right; - buildTree(right, array, h + 1); + buildTree(right, array, rightNode); } } From 791dc35817e3ac5c470c4e131912d74ac560fdcf Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 27 Mar 2017 21:04:26 +0800 Subject: [PATCH 52/96] add MoreThanHalfInArray --- .../wcong/test/algorithm/jzoffer/MinKNum.java | 15 +++++++++ .../jzoffer/MoreThanHalfInArray.java | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java new file mode 100644 index 0000000..3e5c372 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java @@ -0,0 +1,15 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for array and partition and sorting + * Created by hzwangcong on 2017/3/27. + */ +public class MinKNum { + + public static void main(String[] args) { + + } + + + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java new file mode 100644 index 0000000..54f333b --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java @@ -0,0 +1,33 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.eclipse.core.runtime.Assert; + +/** + * test for array + * give a array and there is a num appear more than a half find it + * Created by hzwangcong on 2017/3/27. + */ +public class MoreThanHalfInArray { + + public static void main(String[] args) { + Assert.isTrue(halfNum(new int[]{1, 2, 1, 1, 3, 1, 4}) == 1); + } + + public static int halfNum(int[] array) { + int num = array[0]; + int count = 1; + for (int i = 1; i < array.length; i++) { + if (array[i] == num) { + count += 1; + } else { + count -= 1; + } + if (count <= 0) { + num = array[i]; + count = 1; + } + } + return num; + } + +} From b8d13ee80205a4f49e910a7601c2fb0b9bad4743 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 10:51:21 +0800 Subject: [PATCH 53/96] add MinKNum --- .../wcong/test/algorithm/jzoffer/MinKNum.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java index 3e5c372..1d6d535 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java @@ -1,5 +1,9 @@ package org.wcong.test.algorithm.jzoffer; +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; + /** * test for array and partition and sorting * Created by hzwangcong on 2017/3/27. @@ -7,9 +11,80 @@ public class MinKNum { public static void main(String[] args) { + int[] array = new int[]{4, 5, 2, 1, 2, 4, 5, 6}; + minKNumPartition(array, 2); + minKNumSort(array, 2); + } + + public static int[] minKNumPartition(int[] array, int k) { + if (array == null || k <= 0) { + return null; + } + if (array.length <= k) { + return array; + } + int start = 0, end = array.length - 1; + while (end != k) { + int middle = start + (end - start) / 2; + int middleValue = array[middle]; + array[middle] = array[end]; + array[end] = middleValue; + int moreIndex = 0, lessIndex = end - 1; + while (moreIndex <= lessIndex) { + while (moreIndex < lessIndex && array[moreIndex] <= middleValue) { + moreIndex += 1; + } + while (lessIndex > moreIndex && array[lessIndex] > middleValue) { + lessIndex -= 1; + } + int temp = array[moreIndex]; + array[moreIndex] = array[lessIndex]; + array[lessIndex] = temp; + moreIndex += 1; + lessIndex -= 1; + } + int temp = array[moreIndex]; + array[moreIndex] = array[end]; + array[end] = temp; + if (moreIndex >= k) { + end = moreIndex; + } else { + start = moreIndex; + } + } + return Arrays.copyOf(array, k); } + public static int[] minKNumSort(int[] array, int k) { + if (array == null || k <= 0) { + return null; + } + if (array.length <= k) { + return array; + } + PriorityQueue minKQueue = new PriorityQueue<>(k, new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + }); + for (int i = 0; i < array.length; i++) { + if (minKQueue.size() < k) { + minKQueue.add(array[i]); + } else { + minKQueue.add(array[i]); + minKQueue.poll(); + } + } + int[] result = new int[k]; + int index = 0; + for (int num : minKQueue) { + result[index] = num; + index += 1; + } + return result; + } } From 142c744cb294d5165b495169abaa3ce240bd29a7 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 14:32:26 +0800 Subject: [PATCH 54/96] add MinKNum --- .../algorithm/jzoffer/MaxSumSubArray.java | 34 ++++++++++++++++ .../wcong/test/algorithm/jzoffer/MinKNum.java | 40 +++++++++---------- .../algorithm/jzoffer/NumberOf1BeforeN.java | 22 ++++++++++ .../jzoffer/ReverseOrderPareInArray.java | 8 ++++ 4 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java new file mode 100644 index 0000000..bd882da --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java @@ -0,0 +1,34 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for array + * give a array find the max sum of sub array + * for example 1,-2,3,10,-4,7,2,-5 max 18 + * Created by hzwangcong on 2017/3/28. + */ +public class MaxSumSubArray { + + + public static void main(String[] args) { + Assert.isTrue(maxSum(new int[]{1, -2, 3, 10, -4, 7, 2, -5}) == 18); + } + + public static int maxSum(int[] array) { + int maxSum = array[0]; + int currentSum = array[0]; + for (int i = 1; i < array.length; i++) { + if (currentSum <= 0) { + currentSum = array[i]; + }else{ + currentSum+=array[i]; + } + if (currentSum > maxSum) { + maxSum = currentSum; + } + } + return maxSum; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java index 1d6d535..8dcac5c 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java @@ -5,13 +5,13 @@ import java.util.PriorityQueue; /** - * test for array and partition and sorting + * test for array and partition and sorting TODO * Created by hzwangcong on 2017/3/27. */ public class MinKNum { public static void main(String[] args) { - int[] array = new int[]{4, 5, 2, 1, 2, 4, 5, 6}; + int[] array = new int[]{4, 5, 7, 1, 2, 4, 5, 6}; minKNumPartition(array, 2); minKNumSort(array, 2); } @@ -25,32 +25,32 @@ public static int[] minKNumPartition(int[] array, int k) { return array; } int start = 0, end = array.length - 1; - while (end != k) { + while (end != k - 1) { int middle = start + (end - start) / 2; int middleValue = array[middle]; array[middle] = array[end]; array[end] = middleValue; - int moreIndex = 0, lessIndex = end - 1; - while (moreIndex <= lessIndex) { - while (moreIndex < lessIndex && array[moreIndex] <= middleValue) { - moreIndex += 1; + int i = start - 1; + for (int j = start; j < end; j++) { + if (array[j] <= middleValue) { + i += 1; + if (i != j) { + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } } - while (lessIndex > moreIndex && array[lessIndex] > middleValue) { - lessIndex -= 1; - } - int temp = array[moreIndex]; - array[moreIndex] = array[lessIndex]; - array[lessIndex] = temp; - moreIndex += 1; - lessIndex -= 1; } - int temp = array[moreIndex]; - array[moreIndex] = array[end]; + i += 1; + int temp = array[i]; + array[i] = array[end]; array[end] = temp; - if (moreIndex >= k) { - end = moreIndex; + if (i == k - 1) { + end = i; + } else if (i > k - 1) { + end = k - 1; } else { - start = moreIndex; + start = i + 1; } } return Arrays.copyOf(array, k); diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java new file mode 100644 index 0000000..4e8f64d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java @@ -0,0 +1,22 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for number and divide and conquer TODO + * give a number n count all the 1 appear from 1 to n; + * for example n=11 count = 3 + * Created by wcong on 2017/3/28. + */ +public class NumberOf1BeforeN { + + public static void main(String[] args) { + + } + + public static int count1(int n) { + if (n < 1) { + return 0; + } + return 0; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java new file mode 100644 index 0000000..f73d39d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java @@ -0,0 +1,8 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for array and recursive TODO + * Created by wcong on 2017/3/28. + */ +public class ReverseOrderPareInArray { +} From a5c4bc7896713aea28dbc96e3c5221f9361ad8a3 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 16:07:33 +0800 Subject: [PATCH 55/96] add NumberOf1BeforeN --- .../wcong/test/algorithm/jzoffer/MinKNum.java | 2 +- .../algorithm/jzoffer/NumberOf1BeforeN.java | 47 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java index 8dcac5c..8ad0f9c 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java @@ -5,7 +5,7 @@ import java.util.PriorityQueue; /** - * test for array and partition and sorting TODO + * test for array and partition and sorting * Created by hzwangcong on 2017/3/27. */ public class MinKNum { diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java index 4e8f64d..15697e4 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java @@ -1,7 +1,9 @@ package org.wcong.test.algorithm.jzoffer; +import org.eclipse.core.runtime.Assert; + /** - * test for number and divide and conquer TODO + * test for number and divide and conquer * give a number n count all the 1 appear from 1 to n; * for example n=11 count = 3 * Created by wcong on 2017/3/28. @@ -9,14 +11,53 @@ public class NumberOf1BeforeN { public static void main(String[] args) { - + Assert.isTrue(count1(11) == 4); + Assert.isTrue(count1(21) == 13); } + // for example 11 have 4 : 1 10 11 , 21 have 13 public static int count1(int n) { if (n < 1) { return 0; } - return 0; + if (n < 10) { + return 1; + } + int current = n; + int exponent = 0; + int maxTen = 1; + while (current >= 10) { + maxTen *= 10; + exponent += 1; + current /= 10; + } + return count1(n, maxTen, exponent); + } + + private static int count1(int n, int maxTen, int exponent) { + int count = 0; + if (n / maxTen == 1) { + count += n - maxTen + 1; + } else { + count += maxTen; + } + int lowExponent = countExponent(exponent); + while (n > maxTen) { + count += lowExponent; + n -= maxTen; + } + count += count1(n); + return count; + } + + private static int countExponent(int exponent) { + if (exponent == 0) { + return 0; + } + if (exponent == 1) { + return 1; + } + return 10 * countExponent(exponent - 1) + (int) Math.pow(10, exponent - 1); } } From 3e176b4a24627f981cfdaf961aecea42d38db25f Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 16:36:27 +0800 Subject: [PATCH 56/96] add ReverseOrderPareInArray --- .../jzoffer/ReverseOrderPareInArray.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java index f73d39d..ad55de3 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java @@ -1,8 +1,55 @@ package org.wcong.test.algorithm.jzoffer; +import org.springframework.util.Assert; + /** * test for array and recursive TODO * Created by wcong on 2017/3/28. */ public class ReverseOrderPareInArray { + + public static void main(String[] args) { + Assert.isTrue(reversPairsCount(new int[]{7, 5, 6, 4}) == 5); + } + + public static int reversPairsCount(int[] array) { + if (array == null || array.length < 2) { + return 0; + } + int[] copy = new int[array.length]; + for (int i = 0; i < array.length; i++) { + copy[i] = array[i]; + } + return count(array, copy, 0, array.length - 1); + } + + private static int count(int[] original, int[] copy, int start, int end) { + if (start == end) { + copy[start] = original[start]; + return 0; + } + int length = (end - start) / 2; + int left = count(copy, original, start, start + length); + int right = count(copy, original, start + length + 1, end); + int merge = 0; + int leftEnd = start + length; + int rightEnd = end; + int current = end; + while (leftEnd >= start && rightEnd > (start + length)) { + if (original[leftEnd] > original[rightEnd]) { + merge += rightEnd - start - length; + copy[current--] = original[leftEnd--]; + } else { + copy[current--] = original[rightEnd--]; + } + } + while (leftEnd >= start) { + copy[current--] = original[leftEnd--]; + } + while (rightEnd > start + length) { + copy[current--] = original[rightEnd--]; + } + return left + right + merge; + } + } From 5e4335cf7e37846d4b08e97babaa74d0c7458e51 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 16:47:34 +0800 Subject: [PATCH 57/96] add CommonNodeInTwoLinkedList --- .../jzoffer/CommonNodeInTwoLinkedList.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java new file mode 100644 index 0000000..21d16ef --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java @@ -0,0 +1,55 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; +import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; +import org.wcong.test.algorithm.jzoffer.util.LinkedListNode; + +/** + * test for linked list + * give to linked list find the first common node + * Created by wcong on 2017/3/28. + */ +public class CommonNodeInTwoLinkedList { + + public static void main(String[] args) { + Assert.isTrue(commmoNode(BuildLinkedList.makeOne(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}).root, BuildLinkedList.makeOne(new int[]{11, 12, 12, 14, 5, 6, 7, 8, 9}).root) == 5); + } + + public static int commmoNode(LinkedListNode list1, LinkedListNode list2) { + if (list1 == null || list2 == null) { + throw new RuntimeException("wrong param"); + } + int list1Length = 1, list2Length = 1; + LinkedListNode node = list1; + while (node.next != null) { + list1Length += 1; + node = node.next; + } + node = list2; + while (node.next != null) { + list2Length += 1; + node = node.next; + } + LinkedListNode startNode1 = list1; + LinkedListNode startNode2 = list2; + if (list1Length > list2Length) { + int length = list1Length - list2Length; + for (int i = 0; i < length; i++) { + startNode1 = startNode1.next; + } + } else if (list1Length < list2Length) { + int length = list2Length - list1Length; + for (int i = 0; i < length; i++) { + startNode2 = startNode2.next; + } + } + while (true) { + if (startNode1.value == startNode2.value) { + return startNode1.value; + } + startNode1 = startNode1.next; + startNode2 = startNode2.next; + } + } + +} From a8393b2897196c689283006f8b96028980f2d29c Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 20:03:28 +0800 Subject: [PATCH 58/96] add CountInSortedArray --- .../algorithm/jzoffer/CountInSortedArray.java | 51 +++++++++++++++++++ .../jzoffer/TwoDifferentNumInArray.java | 43 ++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java new file mode 100644 index 0000000..d57ecba --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java @@ -0,0 +1,51 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for array and binary search + * give a sorted array count the target appear num + * Created by hzwangcong on 2017/3/28. + */ +public class CountInSortedArray { + + public static void main(String[] args) { + + } + + private static int countInSortedArray(int[] array, int target) { + int index = index(array, 0, array.length - 1, target); + if (index == 0) { + return 0; + } + int count = 1; + for (int i = index - 1; i > 0; i--) { + if (array[i] == target) { + count += 1; + } else { + break; + } + } + for (int i = index + 1; i < array.length; i++) { + if (array[i] == target) { + count += 1; + } else { + break; + } + } + return count; + } + + public static int index(int[] array, int start, int end, int target) { + if (start < end) { + return -1; + } + int middle = start + (end - start) / 2; + if (array[middle] == target) { + return middle; + } else if (array[middle] > target) { + return index(array, start, middle - 1, target); + } else { + return index(array, middle + 1, end, target); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java new file mode 100644 index 0000000..b92f87d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java @@ -0,0 +1,43 @@ +package org.wcong.test.algorithm.jzoffer; + +/** + * test for bit operation and array + * give a array two of the numbers appears only once others all appears twice,find the tow number + * Created by wcong on 2017/3/28. + */ +public class TwoDifferentNumInArray { + + public static void main(String[] args) { + twoNumbers(new int[]{1, 2, 3, 4, 5, 6, 4, 3, 2, 5}); + } + + + public static int[] twoNumbers(int[] array) { + if (array == null || array.length < 2) { + return null; + } + int result = 0; + for (int num : array) { + result ^= num; + } + int bitIndex = 0; + while (result != 0) { + if ((result & 1) != 0) { + break; + } + result = result >> 1; + bitIndex += 1; + } + int num1 = 0; + int num2 = 0; + for (int num : array) { + if (((num >> bitIndex) & 1) == 0) { + num1 ^= num; + } else { + num2 ^= num; + } + } + return new int[]{num1, num2}; + } + +} From b6e3f79f410a10a6893401509266394008ae4f8a Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 20:16:04 +0800 Subject: [PATCH 59/96] add SortedArraySumTarget --- .../jzoffer/SortedArraySumTarget.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java b/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java new file mode 100644 index 0000000..c323b1e --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +import java.util.Arrays; + +/** + * test for array and tow pointer + * give a sorted array return two num sum to a target + * for example 1,2,4,7,11,15 target 12 + * Created by wcong on 2017/3/28. + */ +public class SortedArraySumTarget { + + public static void main(String[] args) { + Assert.isTrue(Arrays.equals(sumTarget(new int[]{1, 2, 4, 7, 11, 15}, 12), new int[]{0, 4})); + Assert.isTrue(Arrays.equals(sumTarget(new int[]{1, 2, 4, 7, 11, 15}, 11), new int[]{2, 3})); + } + + public static int[] sumTarget(int[] array, int target) { + if (array == null || array.length < 2) { + return null; + } + int start = 0; + int end = array.length - 1; + int sum; + while (start < end) { + sum = array[start] + array[end]; + if (sum == target) { + return new int[]{start, end}; + } else if (sum > target) { + end -= 1; + } else { + start += 1; + } + } + return null; + } + +} From c845c1fa884bc0e96751576f23929e903a2fa333 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 28 Mar 2017 21:14:27 +0800 Subject: [PATCH 60/96] add SortedArraySumTargetSubSerial --- .../SortedArraySumTargetSubSerial.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java b/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java new file mode 100644 index 0000000..9f72d5c --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java @@ -0,0 +1,46 @@ +package org.wcong.test.algorithm.jzoffer; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * test for array and two pointer + * give a sorted array return all serial sub array sum to target + * for example a array 1,2,3,4,5,6,7,8 target 15 will give {1,2,3,4,5} {4,5,6} {7,8} + * Created by wcong on 2017/3/28. + */ +public class SortedArraySumTargetSubSerial { + + + public static void main(String[] args) { + subSerial(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 15); + } + + public static List subSerial(int[] array, int target) { + if (array == null || array.length < 2) { + return null; + } + List resultList = new LinkedList<>(); + int left = 0, right = 1; + int sum = array[left] + array[right]; + while (right < array.length) { + if (sum > target) { + if (left == right) { + break; + } + sum -= array[left++]; + } else if (sum < target) { + if (right == array.length - 1) { + break; + } + sum += array[++right]; + } + if (sum == target) { + resultList.add(Arrays.copyOfRange(array, left, right + 1)); + sum -= array[left++]; + } + } + return resultList; + } +} From ff721926d78d7be9aba4aa8659fe613822c024ad Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 29 Mar 2017 11:05:35 +0800 Subject: [PATCH 61/96] add UglyNumber --- .../test/algorithm/jzoffer/UglyNumber.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java new file mode 100644 index 0000000..ef974a4 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java @@ -0,0 +1,39 @@ +package org.wcong.test.algorithm.jzoffer; + +import org.springframework.util.Assert; + +/** + * test for number + * ugly number only contains 2,3,4 for multiply count target number of ugly number + * Created by wcong on 2017/3/29. + */ +public class UglyNumber { + + public static void main(String[] args) { + Assert.isTrue(nThUglyNumber(9) == 12); + Assert.isTrue(nThUglyNumber(10) == 15); + } + + public static int nThUglyNumber(int n) { + int[] ugly = new int[n + 1]; + ugly[0] = 1; + int index2 = 0; + int index3 = 0; + int index5 = 0; + for (int i = 1; i <= n; i++) { + int min = Math.min(Math.min(ugly[index2] * 2, ugly[index3] * 3), ugly[index5] * 5); + ugly[i] = min; + while (ugly[index2] * 2 <= min) { + index2 += 1; + } + while (ugly[index3] * 3 <= min) { + index3 += 1; + } + while (ugly[index5] * 5 <= min) { + index5 += 1; + } + } + return ugly[n]; + } + +} From 32655aa3f34ea0f90d89be14697e6eb3e28c55be Mon Sep 17 00:00:00 2001 From: wcong Date: Fri, 31 Mar 2017 16:49:44 +0800 Subject: [PATCH 62/96] add some dp problem --- .../org/wcong/test/algorithm/basic/Graph.java | 48 ++++++++ .../org/wcong/test/algorithm/basic/Heap.java | 105 ++++++++++++++++++ .../algorithm/basic/MinimumSpanningTree.java | 59 ++++++++++ .../test/algorithm/dp/AllPermutation.java | 8 ++ .../test/algorithm/dp/BreakingAString.java | 30 +++++ .../wcong/test/algorithm/dp/EditDistance.java | 31 ++++++ .../dp/LongestCommonSubsequence.java | 41 +++++++ .../dp/LongestPalindromeSubsequence.java | 46 ++++++++ .../dp/MatrixChainMultiplication.java | 40 +++++++ .../wcong/test/algorithm/dp/PrintNearly.java | 33 ++++++ .../wcong/test/algorithm/dp/RodCutting.java | 29 +++++ 11 files changed, 470 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/basic/Graph.java create mode 100644 src/main/java/org/wcong/test/algorithm/basic/Heap.java create mode 100644 src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/EditDistance.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/RodCutting.java diff --git a/src/main/java/org/wcong/test/algorithm/basic/Graph.java b/src/main/java/org/wcong/test/algorithm/basic/Graph.java new file mode 100644 index 0000000..5eeac42 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/basic/Graph.java @@ -0,0 +1,48 @@ +package org.wcong.test.algorithm.basic; + +import java.util.List; +import java.util.Map; + +/** + * represent a graph + * adjacent list + * Created by wcong on 2017/3/29. + */ +public class Graph { + + + public static class Edge { + + public Vertex from; + + public Vertex to; + + public int distance; + + } + + public static class Vertex { + public int value; + + public int distance; + + public Vertex last; + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof Vertex)) { + return false; + } + return value == ((Vertex) o).value; + } + } + + public List edges; + + public Map> adjacentMap; + + public void addEdge(Edge edge) { + edges.add(edge); + adjacentMap.get(edge.from).add(edge.to); + } +} diff --git a/src/main/java/org/wcong/test/algorithm/basic/Heap.java b/src/main/java/org/wcong/test/algorithm/basic/Heap.java new file mode 100644 index 0000000..0b430ef --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/basic/Heap.java @@ -0,0 +1,105 @@ +package org.wcong.test.algorithm.basic; + +import java.util.Arrays; + +/** + * a heap data structure + * 1 property max-heap there is max-heap property and min-heap there is min-heap property + * 2 operation + * 1. max-heapify : give a index,assume it's children is all satisfied ,make sure index is satisfied + * 2. build max-heap : make self a max-heap + * 3. heap-sort + * 4. max-heap-insert + * 5. heap-extract-max + * 6. heap-increase-key + * 7. heap-maximum + * Created by wcong on 2017/3/29. + */ +public class Heap { + + private int[] array; + + public Heap(int[] array) { + assert array != null; + this.array = Arrays.copyOf(array, array.length); + } + + /** + * initialization:priory to the first iteration of loop,i=[n/2],each node[n/2]+1,[n/2]+2,n is a leaf and thus the root + */ + public void buildMaxHeap() { + if (array == null || array.length <= 1) { + return; + } + int end = array.length / 2; + for (int i = end - 1; i >= 0; i++) { + maxHeapify(i, array.length - 1); + } + } + + public int maximun() { + return array[0]; + } + + public int heapExtractMax() { + return 0; + } + + public void maxHeapInsert(int add) { + int[] newArray = new int[array.length + 1]; + for (int i = 0; i < array.length; i++) { + newArray[i] = array[i]; + } + heapIncreaseKey(newArray.length - 1, add); + } + + + public void heapIncreaseKey(int index, int k) { + array[index] = k; + while (index > 0) { + int parent = (index + 1) / 2 - 1; + if (array[parent] < array[index]) { + int temp = array[parent]; + array[parent] = array[index]; + array[index] = temp; + index = parent; + } else { + break; + } + } + } + + public void maxHeapify(int index, int length) { + int left = index * 2 + 1; + int right = left + 1; + int maxIndex = index; + if (left <= length && array[left] > array[maxIndex]) { + maxIndex = left; + } + if (right <= length && array[right] > array[maxIndex]) { + maxIndex = right; + } + if (maxIndex == index) { + return; + } + int temp = array[index]; + array[index] = array[maxIndex]; + array[maxIndex] = temp; + maxHeapify(maxIndex, length); + } + + public static void heapSort(int[] array) { + Heap heap = new Heap(array); + heap.buildMaxHeap(); + int end = array.length - 1; + while (end > 0) { + int temp = array[0]; + array[0] = array[end]; + array[end] = temp; + end -= 1; + heap.maxHeapify(0, end); + } + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java b/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java new file mode 100644 index 0000000..3b5b580 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java @@ -0,0 +1,59 @@ +package org.wcong.test.algorithm.basic; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.Set; + +/** + * test for graph + * Created by wcong on 2017/3/29. + */ +public class MinimumSpanningTree { + + + public List kruskal(Graph graph) { + List mini = new ArrayList<>(); + Set vertexSet = new HashSet<>(); + Queue priorityQueue = new PriorityQueue<>(graph.edges.size(), new Comparator() { + @Override + public int compare(Graph.Edge o1, Graph.Edge o2) { + return o2.distance - o1.distance; + } + }); + priorityQueue.addAll(graph.edges); + while (!priorityQueue.isEmpty()) { + Graph.Edge edge = priorityQueue.poll(); + if (!(vertexSet.contains(edge.from) && vertexSet.contains(edge.to))) { + mini.add(edge); + vertexSet.add(edge.from); + vertexSet.add(edge.to); + } + } + return mini; + } + + public List prim(Graph graph) { + PriorityQueue priorityQueue = new PriorityQueue<>(graph.adjacentMap.keySet().size(), new Comparator() { + @Override + public int compare(Graph.Vertex o1, Graph.Vertex o2) { + return o2.distance - o1.distance; + } + }); + for (Graph.Vertex vertex : graph.adjacentMap.keySet()) { + vertex.distance = Integer.MAX_VALUE; + priorityQueue.add(vertex); + } + Graph.Vertex first = priorityQueue.poll(); + first.distance = 0; + priorityQueue.add(first); + while (!priorityQueue.isEmpty()) { + Graph.Vertex min = priorityQueue.poll(); + + } + return null; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java b/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java new file mode 100644 index 0000000..45e36f1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java @@ -0,0 +1,8 @@ +package org.wcong.test.algorithm.dp; + +/** + * give a string of unique character ,return all permutation + * Created by wcong on 2017/3/31. + */ +public class AllPermutation { +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java b/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java new file mode 100644 index 0000000..d95e7e4 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java @@ -0,0 +1,30 @@ +package org.wcong.test.algorithm.dp; + +/** + * given a string S with n characters and an array containing the break points, compute + * the lowest cost for a sequence of breaks, along with a sequence of breaks that + * achieves this cost. + * length of 20 points 2,8,10 + * Created by wcong on 2017/3/31. + */ +public class BreakingAString { + public static void main(String[] args) { + + } + + public static int minimumCost(String a, int[] point) { + return minimumCost(a, 0, a.length() - 1, point, 0, point.length - 1); + } + + public static int minimumCost(String a, int start, int end, int[] point, int pointStart, int pointEnd) { + if (start >= end || pointStart >= pointEnd) { + return 0; + } + int length = end - start + 1; + int left = minimumCost(a, point[pointStart], end, point, pointStart + 1, pointEnd); + int right = minimumCost(a, start, point[pointEnd], point, pointStart, pointEnd - 1); + return left < right ? left + length : right + length; + } + + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java b/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java new file mode 100644 index 0000000..f3c55de --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java @@ -0,0 +1,31 @@ +package org.wcong.test.algorithm.dp; + +/** + * give two strings a,b calculate the distance for b transform to b + * use + * add insert one char + * delete delete one char + * replace replace one char + * return the minimum distance + * Created by wcong on 2017/3/31. + */ +public class EditDistance { + + public static void main() { + } + + public static int mininumEditDistance(String a, String b) { + int[][] result = new int[a.length()][b.length()]; + for (int i = 0; i < a.length(); i++) { + for (int j = 0; j < b.length(); j++) { + if (a.charAt(i) == b.charAt(j)) { + result[i + 1][j + 1] = result[i][j] + 1; + } else { + result[i + 1][j + 1] = 1 + Math.min(Math.min(result[i + 1][j], result[i][j + 1]), result[i][j]); + } + } + } + return result[a.length()][b.length()]; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java b/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java new file mode 100644 index 0000000..bf00be8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.dp; + +/** + * give two string a,b find the longest common sub sequence + * Created by wcong on 2017/3/31. + */ +public class LongestCommonSubSequence { + + public static void main(String[] args) { + + } + + public static int longest(String a, String b) { + int[][] result = new int[a.length() + 1][b.length() + 1]; + if (a.charAt(0) == b.charAt(0)) { + result[1][1] = 1; + } + for (int i = 0; i < b.length(); i++) { + if (a.charAt(0) == b.charAt(i)) { + result[1][i + 1] = 1; + } + } + for (int i = 1; i < a.length(); i++) { + for (int j = 0; j < b.length(); j++) { + if (a.charAt(i) == b.charAt(j)) { + result[i][j] = result[i - 1][j] + 1; + } + } + } + int max = 0; + for (int i = 0; i < a.length(); i++) { + for (int j = 0; j < b.length(); j++) { + if (result[i][j] > max) { + max = result[i][j]; + } + } + } + return max; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java b/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java new file mode 100644 index 0000000..614cca6 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java @@ -0,0 +1,46 @@ +package org.wcong.test.algorithm.dp; + +import org.eclipse.core.runtime.Assert; + +/** + * give a string find the longest palindrome sub sequence + * Created by wcong on 2017/3/31. + */ +public class LongestPalindromeSubsequence { + + public static void main(String[] args) { + Assert.isTrue(palindrome("cabdbae") == 5); + } + + public static int palindrome(String a) { + int[][] result = new int[a.length()][a.length()]; + for (int i = 0; i < a.length(); i++) { + result[i][i] = 1; + } + for (int i = 1; i < a.length(); i++) { + for (int j = 0; j < i; j++) { + if (a.charAt(i) == a.charAt(j)) { + if (i - j - 1 == 1) { + result[i][j] = 3; + } else if (i - 1 > 0 && j + 1 < i - 1) { + if (result[i - 1][j + 1] > 0) { + result[i][j] = result[i - 1][j + 1] + 2; + } + } else { + result[i][j] = 1; + } + } + } + } + int max = 1; + for (int i = 0; i < a.length(); i++) { + for (int j = 0; j < a.length(); j++) { + if (result[i][j] > max) { + max = result[i][j]; + } + } + } + return max; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java b/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java new file mode 100644 index 0000000..d459444 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.dp; + +/** + * we are given a sequence of matrix to to multiplied + * and we wish to computer the product + * TODO + * Created by wcong on 2017/3/30. + */ +public class MatrixChainMultiplication { + + static class MatrixSymbol { + int row = 1; + int column = 1; + + public MatrixSymbol mulitply(MatrixSymbol other) { + MatrixSymbol matrixSymbol = new MatrixSymbol(); + matrixSymbol.row = row; + matrixSymbol.column = other.column; + return matrixSymbol; + } + } + + public static void main(String[] args) { + + } + + public static int multipiedNum(MatrixSymbol[] matrixArray) { + int[] multipliedNum = new int[matrixArray.length + 1]; + MatrixSymbol[] multipliedMetrix = new MatrixSymbol[matrixArray.length + 1]; + for (int i = 1; i < matrixArray.length; i++) { + int max = -1; + int lastMultiplied = 0; + MatrixSymbol lastMatrixSybmol = new MatrixSymbol(); + for (int j = i; j > 0; j--) { + lastMultiplied += matrixArray[j].row; + } + } + return 0; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java b/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java new file mode 100644 index 0000000..98cae57 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java @@ -0,0 +1,33 @@ +package org.wcong.test.algorithm.dp; + +/** + * Consider the problem of neatly printing a paragraph with a monospaced font (all + * characters having the same width) on a printer. + * The input text is a sequence of n words of lengths l1; l2; : : : ; ln, measured in characters. + * We want to print this paragraph neatly on a number of lines that hold a maximum of M characters each. + * Our criterion of “neatness” is as follows. If a given line contains words i through j , + * where i <= j , and we leave exactly one space between words, the number of extra + * We wish to minimize the left space to right. + * Created by wcong on 2017/3/31. + */ +public class PrintNearly { + + public static void main(String[] args) { + + } + + public static int paintNum(int[] array, int m) { + int[][] result = new int[array.length + 1][array.length + 1]; + for (int i = 0; i < array.length; i++) { + for (int j = 0; j <= i; j++) { + if (array[i] + result[i][j] <= m) { + result[i + 1][j + 1] = result[i][j + 1] + array[i]; + } else { + result[i + 1][j + 1] = result[i - 1][j] > result[i][j - 1] ? result[i - 1][j] : result[i][j - 1]; + } + } + } + return result[array.length][array.length]; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java b/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java new file mode 100644 index 0000000..c14a7b8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java @@ -0,0 +1,29 @@ +package org.wcong.test.algorithm.dp; + +/** + * given a rod of length n inches and a table of n prices p[i] for i=1,2,3.... + * determine the maximum revenue r(n) by cutting up rod and selling prices + * Created by wcong on 2017/3/30. + */ +public class RodCutting { + + public static void main(String[] args) { + + } + + public static int rodCutting(int[] array, int n) { + int[] revenueArray = new int[n + 1]; + for (int i = 1; i <= n; i++) { + int max = array[i]; + for (int j = 1; j < i; j++) { + int revenue = revenueArray[j] + revenueArray[i - j]; + if (revenue > max) { + max = revenue; + } + } + revenueArray[i] = max; + } + return revenueArray[n]; + } + +} From 534279f8eb7f29de9c55088210a8ac547e8e259c Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 11:10:29 +0800 Subject: [PATCH 63/96] add MaximumPathSum --- .../leetcode/tree/MaximumPathSum.java | 39 +++++++++++++++++++ .../wcong/test/algorithm/tree/BinaryTree.java | 12 ++++-- 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java new file mode 100644 index 0000000..2cd227a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java @@ -0,0 +1,39 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary tree,find the maximum path sum for any path ,not have to include the root,just path + * Created by wcong on 2017/4/1. + */ +public class MaximumPathSum { + + public static void main(String[] args) { + + } + + static class TreeNode { + int value; + TreeNode left; + TreeNode right; + } + + static int max = Integer.MIN_VALUE; + + public static int maximumPathSum(TreeNode root) { + sumTree(root); + return max; + } + + private static int sumTree(TreeNode treeNode) { + if (treeNode == null) { + return 0; + } + int sum = treeNode.value; + sum += Math.max(sumTree(treeNode.left), 0); + sum += Math.max(sumTree(treeNode.right), 0); + if (sum > max) { + max = sum; + } + return sum; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java index c78b0aa..0487ab1 100644 --- a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java @@ -60,7 +60,11 @@ public void deleteNode(int key) { root.key = replace.key; } } else { - + if (key < root.key) { + deleteNodeInternal(root, root.left, key); + } else { + deleteNodeInternal(root, root.right, key); + } } } @@ -71,12 +75,12 @@ private void deleteNodeInternal(Node parent, Node node, int key) { } if (node.key == key) { if (node.right == null && node.left == null) { - if( parent.left == node ){ + if (parent.left == node) { parent.left = null; - }else{ + } else { parent.right = null; } - }else if( node.right == null ){ + } else if (node.right == null) { } } else if (node.key < key) { From 0aeff7eb31099e2dbc0698da6c7c4981287fcc2d Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 15:39:13 +0800 Subject: [PATCH 64/96] add tree --- .../leetcode/tree/BinaryTreePaths.java | 37 +++++++++++++ .../leetcode/tree/InorderSuccessorInBST.java | 44 +++++++++++++++ .../leetcode/tree/InvertBinaryTree.java | 46 ++++++++++++++++ .../LowestCommonAncestorOfABinaryTree.java | 54 +++++++++++++++++++ .../leetcode/tree/SumOfLeftLeaves.java | 35 ++++++++++++ .../algorithm/leetcode/tree/TreeNode.java | 14 +++++ .../leetcode/tree/ValidateBinaryTree.java | 29 ++++++++++ 7 files changed, 259 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java new file mode 100644 index 0000000..c5651ed --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java @@ -0,0 +1,37 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.ArrayList; +import java.util.List; + +/** + * given a binary tree,return all root-to-leaf path + * Created by wcong on 2017/4/1. + */ +public class BinaryTreePaths { + + static class TreeNode { + int value; + TreeNode left; + TreeNode right; + } + + public static void main(String[] args) { + + } + + public List paths(TreeNode treeNode) { + List path = new ArrayList<>(); + findPath(treeNode, "", path); + return path; + } + + private static void findPath(TreeNode treeNode, String prefix, List path) { + if (treeNode == null) { + path.add(prefix); + return; + } + prefix += treeNode.value; + findPath(treeNode.left, prefix, path); + findPath(treeNode.right, prefix, path); + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java new file mode 100644 index 0000000..2360a8d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java @@ -0,0 +1,44 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary search tree and a node in it,find the inorder successor of the node in the bst + * test for inorder tree walk, + * if left child of parent the successor is parent + * if right child of parent the successor is last inorder of left sub tree + * Created by wcong on 2017/4/1. + */ +public class InorderSuccessorInBST { + + public static void main(String[] args) { + + } + + public static TreeNode inOrderSuccessor(TreeNode treeNode, TreeNode findNode) { + return successor(treeNode, null, findNode); + } + + private static TreeNode successor(TreeNode treeNode, TreeNode parent, TreeNode findNode) { + if (treeNode.value == findNode.value) { + if (parent == null) { + return null; + } else if (parent.left == treeNode) { + return parent; + } else { + TreeNode successor = parent.left; + while (!(successor.left == null && successor.right == null)) { + if (successor.right != null) { + successor = successor.right; + continue; + } + successor = successor.left; + } + return successor; + } + } else if (findNode.value < treeNode.value) { + return successor(treeNode.left, treeNode, findNode); + } else { + return successor(treeNode.right, treeNode, findNode); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java new file mode 100644 index 0000000..1521d35 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java @@ -0,0 +1,46 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.Stack; + +/** + * as the name says + * Created by wcong on 2017/4/1. + */ +public class InvertBinaryTree { + + public static void main(String[] args) { + + } + + public static void invert(TreeNode root) { + if (root == null) { + return; + } + TreeNode temp = root.left; + root.left = root.right; + root.right = temp; + invert(root.left); + invert(root.right); + } + + public static void invertLoop(TreeNode root) { + if (root == null) { + return; + } + Stack treeNodeStack = new Stack<>(); + treeNodeStack.push(root); + while (!treeNodeStack.isEmpty()) { + TreeNode treeNode = treeNodeStack.pop(); + TreeNode temp = treeNode.left; + treeNode.left = treeNode.right; + treeNode.right = temp; + if (treeNode.left != null) { + treeNodeStack.push(treeNode.left); + } + if (treeNode.right != null) { + treeNodeStack.push(treeNode.right); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java new file mode 100644 index 0000000..8a047fe --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java @@ -0,0 +1,54 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.LinkedList; +import java.util.List; + +/** + * give a binary tree, find the lowest common ancestor of given two node + * Created by wcong on 2017/4/1. + */ +public class LowestCommonAncestorOfABinaryTree { + + public static void main(String[] args) { + + } + + public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) { + List path1 = new LinkedList<>(); + List path2 = new LinkedList<>(); + path1.add(root); + path2.add(root); + findNode(root, node1, path1); + findNode(root, node2, path2); + for (int i = 0; i < path1.size() && i < path2.size(); i++) { + if (path1.get(i) != path2.get(i)) { + return path1.get(i - 1); + } + } + return null; + } + + private static boolean findNode(TreeNode treeNode, TreeNode findNode, List path) { + if (treeNode.value == findNode.value) { + return true; + } else { + if (treeNode.left != null) { + path.add(treeNode.left); + if (findNode(treeNode.left, findNode, path)) { + return true; + } else { + path.remove(path.size() - 1); + } + } + if (treeNode.right != null) { + path.add(treeNode.right); + if (findNode(treeNode.right, findNode, path)) { + return true; + } else { + path.remove(path.size() - 1); + } + } + return false; + } + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java new file mode 100644 index 0000000..aecf522 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java @@ -0,0 +1,35 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.Stack; + +/** + * sum all of the leaves of the tree + * Created by wcong on 2017/4/1. + */ +public class SumOfLeftLeaves { + + public static void main(String[] args) { + + } + + public static int sumLeft(TreeNode root) { + int sum = 0; + if (root == null) { + return sum; + } + Stack treeNodeStack = new Stack<>(); + treeNodeStack.push(root); + while (!treeNodeStack.isEmpty()) { + TreeNode treeNode = treeNodeStack.pop(); + if (treeNode.right != null) { + treeNodeStack.push(treeNode.right); + } + if (treeNode.left != null) { + sum += treeNode.left.value; + treeNodeStack.push(treeNode.left); + } + } + return sum; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java new file mode 100644 index 0000000..ef339f1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java @@ -0,0 +1,14 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * Created by wcong on 2017/4/1. + */ +public class TreeNode { + + int value; + + TreeNode left; + + TreeNode right; + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java new file mode 100644 index 0000000..74913e8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java @@ -0,0 +1,29 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary tree,test if it is a binary tree + * Created by wcong on 2017/4/1. + */ +public class ValidateBinaryTree { + + public static void main(String args) { + } + + static int max = Integer.MIN_VALUE; + + public static boolean validate(TreeNode treeNode) { + if (treeNode == null) { + return true; + } + if (!validate(treeNode.left)) { + return false; + } + if (treeNode.value >= max) { + max = treeNode.value; + } else { + return false; + } + return validate(treeNode.right); + } + +} From d9cb70328233983330e971072603ce4be49636dc Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 15:56:56 +0800 Subject: [PATCH 65/96] add ChangeBinaryTreeToDQueue --- .../jzoffer/ChangeBinaryTreeToDQueue.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java index 3306905..36a5517 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java @@ -19,25 +19,26 @@ public static void main(String[] args) { } public static TreeNode changeToDQueue(Tree tree) { - return changeToDQueue(tree.root); + TreeNode treeNode = changeToDQueue(tree.root, null); + while (treeNode.left != null) { + treeNode = treeNode.left; + } + return treeNode; } - private static TreeNode changeToDQueue(TreeNode treeNode) { - if (treeNode.left == null && treeNode.right == null) { - return treeNode; - } + private static TreeNode changeToDQueue(TreeNode treeNode, TreeNode lastInQueue) { if (treeNode.left != null) { - TreeNode node = changeToDQueue(treeNode.left); - node.right = treeNode; - treeNode.left = node; + lastInQueue = changeToDQueue(treeNode.left, lastInQueue); + } + if (lastInQueue != null) { + lastInQueue.right = treeNode; + treeNode.left = lastInQueue; } - TreeNode right = treeNode; + lastInQueue = treeNode; if (treeNode.right != null) { - TreeNode node = changeToDQueue(treeNode.right); - treeNode.right = node; - node.left = treeNode; + lastInQueue = changeToDQueue(treeNode.right, lastInQueue); } - return right; + return lastInQueue; } } From 9f37eb228bf6e57c620dfa31ab6bc55e7df5886e Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 16:23:56 +0800 Subject: [PATCH 66/96] add DecodeWays --- .../algorithm/leetcode/string/DecodeWays.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java new file mode 100644 index 0000000..71e5f14 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java @@ -0,0 +1,32 @@ +package org.wcong.test.algorithm.leetcode.string; + +import org.eclipse.core.runtime.Assert; + +/** + * string also a dynamic programming + * encode way,A->1,....,Z->26 + * give a string of numbers,count all the ways can be decoded + * for example 12 can be decode two ways 1->A,2->B or 12->L + * Created by wcong on 2017/4/1. + */ +public class DecodeWays { + + public static void main(String[] args) { + Assert.isTrue(decodeWays("123") == 3); + } + + public static int decodeWays(String encode) { + int[] result = new int[encode.length() + 1]; + result[0] = 1; + result[1] = 1; + for (int i = 1; i < encode.length(); i++) { + if (Integer.parseInt(encode.substring(i - 1, i + 1)) <= 26) { + result[i + 1] = result[i - 1] + result[i]; + } else { + result[i + 1] = result[i]; + } + } + return result[encode.length()]; + } + +} From 9a11bb71248bda33e82f70f6fbf349f487728060 Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 17:11:13 +0800 Subject: [PATCH 67/96] add LongestSubStringContainKDistinctWord --- .../LongestSubStringContainKDistinctWord.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java new file mode 100644 index 0000000..0607c6a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java @@ -0,0 +1,40 @@ +package org.wcong.test.algorithm.leetcode.string; + +import org.springframework.util.Assert; + +/** + * give a string find the longest sub string that contains k distinct word + * for example cecba k =2 longest sub string is ece + * Created by wcong on 2017/4/1. + */ +public class LongestSubStringContainKDistinctWord { + + public static void main(String[] args) { + Assert.isTrue(subString("cecba", 2).equals("cec")); + } + + public static String subString(String a, int k) { + int longestStart = 0; + int longestEnd = 0; + int start = 0; + int distinct = 0; + for (int i = 0; i < a.length(); i++) { + if (!a.substring(start, i).contains(a.substring(i, i + 1))) { + distinct += 1; + } + if (distinct == k && i - start > longestEnd - longestStart) { + longestEnd = i; + longestStart = start; + } else if (distinct > k) { + while (start <= i) { + start = start + 1; + if (!a.substring(start + 1, i + 1).contains(a.substring(start, start + 1))) { + break; + } + } + } + } + return a.substring(longestStart, longestEnd + 1); + } + +} From 5143783fcc6407be298bbec4390ec8d5763df226 Mon Sep 17 00:00:00 2001 From: wcong Date: Sat, 1 Apr 2017 18:24:38 +0800 Subject: [PATCH 68/96] add StringMultiply --- .../leetcode/string/StringMultiply.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java new file mode 100644 index 0000000..f312eb2 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java @@ -0,0 +1,17 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * give two string of integer, calculate the product of them + * Created by wcong on 2017/4/1. + */ +public class StringMultiply { + + public static void main(String[] args) { + + } + + public static String multiply(String a, String b) { + return null; + } + +} From 802d6d0b3e03979bc6a8e797d1d604ba3a84e5df Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 9 Apr 2017 14:20:05 +0800 Subject: [PATCH 69/96] optimize InorderSuccessorInBST --- .../leetcode/string/WorldLadder.java | 68 +++++++++++++++++++ .../leetcode/tree/InorderSuccessorInBST.java | 48 +++++-------- 2 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java new file mode 100644 index 0000000..1080362 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java @@ -0,0 +1,68 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @author wcong + * @since 2017/4/3 + */ +public class WorldLadder { + + public static void main(String[] args) { + new WorldLadder().findLadders("hot", "dog", + Arrays.asList(new String[] { "hot", "cog", "dog", "tot", "hog", "hop", "pot", "dot" })); + } + + private int minLength = Integer.MAX_VALUE; + + public List> findLadders(String beginWord, String endWord, List wordList) { + List> resultList = new LinkedList<>(); + List result = new LinkedList<>(); + result.add(beginWord); + findLadders(beginWord, endWord, wordList, result, resultList); + List> minResult = new LinkedList<>(); + for (List soloResult : resultList) { + if (soloResult.size() == minLength) { + minResult.add(soloResult); + } + } + return minResult; + } + + private void findLadders(String beginWord, String endWord, List wordList, List result, + List> resultList) { + if (beginWord.equals(endWord)) { + if (result.size() <= minLength) { + resultList.add(result); + minLength = result.size(); + } + return; + } + if (resultList.size() > minLength) { + return; + } + for (int i = 0; i < wordList.size(); i++) { + if (isOneWordDiffrent(beginWord, wordList.get(i))) { + List leftWordList = new ArrayList(); + leftWordList.addAll(wordList); + leftWordList.remove(i); + List leftResult = new ArrayList(result); + leftResult.add(wordList.get(i)); + findLadders(wordList.get(i), endWord, leftWordList, leftResult, resultList); + } + } + } + + private boolean isOneWordDiffrent(String word, String compare) { + int different = 0; + for (int i = 0; i < word.length(); i++) { + if (word.charAt(i) != compare.charAt(i)) { + different += 1; + } + } + return different == 1; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java index 2360a8d..50c477c 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java @@ -3,42 +3,28 @@ /** * give a binary search tree and a node in it,find the inorder successor of the node in the bst * test for inorder tree walk, - * if left child of parent the successor is parent - * if right child of parent the successor is last inorder of left sub tree + * if right child is not null,find the min node in left sub tree; + * if right child is null,find the last right ancestor. * Created by wcong on 2017/4/1. */ public class InorderSuccessorInBST { - public static void main(String[] args) { + public static void main(String[] args) { - } + } - public static TreeNode inOrderSuccessor(TreeNode treeNode, TreeNode findNode) { - return successor(treeNode, null, findNode); - } - - private static TreeNode successor(TreeNode treeNode, TreeNode parent, TreeNode findNode) { - if (treeNode.value == findNode.value) { - if (parent == null) { - return null; - } else if (parent.left == treeNode) { - return parent; - } else { - TreeNode successor = parent.left; - while (!(successor.left == null && successor.right == null)) { - if (successor.right != null) { - successor = successor.right; - continue; - } - successor = successor.left; - } - return successor; - } - } else if (findNode.value < treeNode.value) { - return successor(treeNode.left, treeNode, findNode); - } else { - return successor(treeNode.right, treeNode, findNode); - } - } + public static TreeNode inOrderSuccessor(TreeNode root, TreeNode findNode) { + TreeNode lastLeftNode = null; + TreeNode compareNode = root; + while (compareNode != null) { + if (findNode.value < compareNode.value) { + lastLeftNode = compareNode; + compareNode = compareNode.left; + } else { + compareNode = compareNode.right; + } + } + return lastLeftNode; + } } From 897a2f923518f0e91ebe20308f2a6a94a15789f8 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 9 Apr 2017 16:00:36 +0800 Subject: [PATCH 70/96] add CoinRow --- .../org/wcong/test/algorithm/dp/CoinRow.java | 27 +++++++++++++++++++ .../test/algorithm/graph/TopologicalSort.java | 10 +++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/dp/CoinRow.java create mode 100644 src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java diff --git a/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java b/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java new file mode 100644 index 0000000..7dddecb --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java @@ -0,0 +1,27 @@ +package org.wcong.test.algorithm.dp; + +/** + * this is a row of n coins whose values are some positive integers c1,c2,....,cn + * not necessarily distinct,the goal is to pick up the maximum amount of money subject + * that no two coins adjacent in the initial row can be picked up. + * + * @author wcong + * @since 2017/4/9 + */ +public class CoinRow { + + public static void main(String[] args) { + + } + + public static int maxCoinSum(int[] array) { + int[] result = new int[array.length]; + result[0] = 0; + result[1] = array[0]; + for (int i = 1; i < array.length; i++) { + result[i + 1] = Math.max(result[i], result[i - 1] + array[i]); + } + return result[array.length]; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java b/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java new file mode 100644 index 0000000..e4da4c1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java @@ -0,0 +1,10 @@ +package org.wcong.test.algorithm.graph; + +/** + * topological sort + * + * @author wcong + * @since 2017/4/9 + */ +public class TopologicalSort { +} From f4a76f71d2a22e24b75a63cb09351fb017f64bf7 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 9 Apr 2017 16:26:48 +0800 Subject: [PATCH 71/96] add ChangeMaking --- .../wcong/test/algorithm/dp/ChangeMaking.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java diff --git a/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java b/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java new file mode 100644 index 0000000..7d20a1a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java @@ -0,0 +1,31 @@ +package org.wcong.test.algorithm.dp; + +/** + * give change for amount n using the minimum number of coin of denomination d1 + * @since 2017/4/9 + */ +public class ChangeMaking { + + public static void main(String[] args) { + + } + + public static int minimumNums(int[] array, int amount) { + int[] result = new int[amount + 1]; + result[0] = 0; + for (int i = 1; i <= amount; i++) { + int min = i; + for (int j = 0; j < array.length; j++) { + if (array[j] > i) { + break; + } + min = Math.min(min, result[i - array[j]] + 1); + } + result[i] = min; + } + return result[amount]; + } + +} From 8dd1532f19ea7a40017f58489842a03401f11a76 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 10 Apr 2017 10:16:03 +0800 Subject: [PATCH 72/96] add data-structure --- .../test/algorithm/leetcode/array/TwoSum.java | 18 ++ .../leetcode/string/StringMultiply.java | 1 + .../test/datastructure/BinarySearchTree.java | 206 ++++++++++++++++++ .../wcong/test/datastructure/LinkedList.java | 67 ++++++ .../test/datastructure/package-info.java | 5 + 5 files changed, 297 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java create mode 100644 src/main/java/org/wcong/test/datastructure/BinarySearchTree.java create mode 100644 src/main/java/org/wcong/test/datastructure/LinkedList.java create mode 100644 src/main/java/org/wcong/test/datastructure/package-info.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java new file mode 100644 index 0000000..d4c6ab9 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java @@ -0,0 +1,18 @@ +package org.wcong.test.algorithm.leetcode.array; + +/** + * give a array of integer and a target,return the indices where two sum equals the target + * assume only one solution + * Created by wcong on 2017/4/5. + */ +public class TwoSum { + + public static void main(String[] args) { + + } + + public static int[] indices(int[] array, int target) { + return null; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java index f312eb2..eae531c 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java @@ -15,3 +15,4 @@ public static String multiply(String a, String b) { } } + diff --git a/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java b/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java new file mode 100644 index 0000000..3757dc0 --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java @@ -0,0 +1,206 @@ +package org.wcong.test.datastructure; + +import java.util.Stack; + +/** + * search,add,delete,traversal for binary search tree + * minimum, maximize, floor, ceiling,selection, rank, + * Created by wcong on 2017/4/5. + */ +public class BinarySearchTree { + + private static class Node { + T value; + Node left; + Node right; + } + + private Node root; + + public Node findIterative(T value) { + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + return node; + } else if (node.value.compareTo(value) > 0) { + node = node.left; + } else { + node = node.right; + } + } + return null; + } + + public Node findRecursive(T value) { + return findNode(root, value); + } + + private Node findNode(Node node, T value) { + if (node == null) { + return null; + } + if (node.value == value) { + return node; + } else if (node.value.compareTo(value) > 0) { + return findNode(node.left, value); + } else { + return findNode(node.right, value); + } + } + + public void insertIterative(T value) { + if (root == null) { + root = new Node<>(); + root.value = value; + return; + } + Node parent = root; + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + return; + } else if (node.value.compareTo(value) > 0) { + parent = node; + node = node.left; + } else { + parent = node; + node = node.right; + } + } + Node insertNode = new Node<>(); + insertNode.value = value; + if (parent.value.compareTo(value) > 0) { + parent.left = insertNode; + } else { + parent.right = insertNode; + } + } + + public void insertRecursive(T value) { + if (root == null) { + root = new Node<>(); + root.value = value; + return; + } + insertNode(root, value); + } + + private void insertNode(Node node, T value) { + if (node == null || node.value.equals(value)) { + return; + } + if (node.value.compareTo(value) > 0) { + if (node.left != null) { + insertNode(node.left, value); + } else { + Node insertNode = new Node<>(); + node.value = value; + node.left = insertNode; + } + } else { + if (node.right != null) { + insertNode(node.right, value); + } else { + Node insertNode = new Node<>(); + node.value = value; + node.right = insertNode; + } + } + } + + public Node deleteMin(Node parent, Node node) { + if (node.left != null) { + return deleteMin(node, node.left); + } + if (parent.left == node) { + parent.left = node.right; + } else { + parent.right = node.right; + } + return node; + } + + private void deleteIterative(T value) { + Node parent = null; + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + break; + } else if (node.value.compareTo(value) > 0) { + parent = node; + node = node.left; + } else { + parent = node; + node = node.right; + } + } + if (node == null) { + return; + } + if (parent == null) { + if (node.right == null) { + root = node.left; + } else { + root = deleteMin(root, root.left); + } + } else { + if (node.right == null) { + if (parent.left == node) { + parent.left = node.left; + } else { + parent.right = node.left; + } + } else { + Node rightMin = deleteMin(node, node.right); + rightMin.left = node.left; + rightMin.right = node.right; + if (parent.left == node) { + parent.left = rightMin; + } else { + parent.right = rightMin; + } + } + } + } + + public void inOrderTraversal() { + inOrderTraversal(root); + } + + private void inOrderTraversal(Node node) { + if (node == null) { + return; + } + inOrderTraversal(node.left); + System.out.println(node.value); + inOrderTraversal(node.right); + } + + private void inOrderTravelsalIterative() { + + } + + private void preOrderTraversalIterative() { + Stack> stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + Node node = stack.pop(); + System.out.println(node.value); + if (node.right != null) { + stack.push(node.right); + } + if (node.left != null) { + stack.push(node.left); + } + } + } + + private void postOrderTraversalIterative() { + Stack> stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + Node node = stack.pop(); + } + } + +} diff --git a/src/main/java/org/wcong/test/datastructure/LinkedList.java b/src/main/java/org/wcong/test/datastructure/LinkedList.java new file mode 100644 index 0000000..84cf1f6 --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/LinkedList.java @@ -0,0 +1,67 @@ +package org.wcong.test.datastructure; + +/** + * search,insert,delete for a linked list + * Created by wcong on 2017/4/5. + */ +public class LinkedList { + + private static class Node { + T value; + Node next; + } + + private Node root; + + public Node find(T value) { + Node node = root; + while (root != null) { + if (root.value.equals(value)) { + return node; + } + node = node.next; + } + return null; + } + + public void insert(T value) { + if (root == null) { + Node insert = new Node<>(); + insert.value = value; + root = insert; + return; + } + Node node = root; + while (true) { + if (node.value == value) { + return; + } + if (node.next == null) { + break; + } + node = node.next; + } + Node insert = new Node<>(); + insert.value = value; + node.next = insert; + } + + public void delete(T value) { + if (root == null) { + return; + } + if (root.value.equals(value)) { + root = root.next; + } + Node parent = root; + Node node = root.next; + while (node != null && node.value != value) { + parent = node; + node = node.next; + } + if (node != null) { + parent.next = node.next; + } + } + +} diff --git a/src/main/java/org/wcong/test/datastructure/package-info.java b/src/main/java/org/wcong/test/datastructure/package-info.java new file mode 100644 index 0000000..3d8954f --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/package-info.java @@ -0,0 +1,5 @@ +/** + * most data structure i should know + * Created by wcong on 2017/4/5. + */ +package org.wcong.test.datastructure; \ No newline at end of file From ba9cfd1406d559641569c001c83d60bcfd27ed8f Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 10 Apr 2017 11:42:09 +0800 Subject: [PATCH 73/96] re arrange problem --- .../jzoffer/{ => tree}/BinaryTreePostOrderWalkRule.java | 2 +- .../algorithm/jzoffer/{ => tree}/ChangeBinaryTreeToDQueue.java | 2 +- .../test/algorithm/jzoffer/{ => tree}/ConstructBinaryTree.java | 2 +- .../org/wcong/test/algorithm/jzoffer/{ => tree}/IsSubTree.java | 2 +- .../test/algorithm/jzoffer/{ => tree}/MirrorOfBinaryTree.java | 2 +- .../algorithm/jzoffer/{ => tree}/PrintBinaryTreeTopDown.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/BinaryTreePostOrderWalkRule.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/ChangeBinaryTreeToDQueue.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/ConstructBinaryTree.java (98%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/IsSubTree.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/MirrorOfBinaryTree.java (93%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => tree}/PrintBinaryTreeTopDown.java (94%) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java index 8cafc0f..5fc8a29 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/BinaryTreePostOrderWalkRule.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java index 36a5517..588555b 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ChangeBinaryTreeToDQueue.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.wcong.test.algorithm.jzoffer.util.BuildTree; import org.wcong.test.algorithm.jzoffer.util.Tree; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java similarity index 98% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java index 49cea52..cb8d69e 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ConstructBinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java index a42c024..1afc1b9 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/IsSubTree.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.wcong.test.algorithm.jzoffer.util.Tree; import org.wcong.test.algorithm.jzoffer.util.TreeNode; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java similarity index 93% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java index e98fbd5..ca3d66c 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MirrorOfBinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.wcong.test.algorithm.jzoffer.util.Tree; import org.wcong.test.algorithm.jzoffer.util.TreeNode; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java similarity index 94% rename from src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java index 39761f7..359076d 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintBinaryTreeTopDown.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.tree; import org.wcong.test.algorithm.jzoffer.util.Tree; import org.wcong.test.algorithm.jzoffer.util.TreeNode; From a45e731155b9f28c1ada02559a459a541eb7e60c Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 10 Apr 2017 11:51:27 +0800 Subject: [PATCH 74/96] optimize --- .../algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java index 5fc8a29..67bd5cf 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java @@ -3,7 +3,7 @@ import org.springframework.util.Assert; /** - * test for binary tree post-order walk analysis + * test for binary search tree post-order walk analysis * give a array of integer judge is binary search tree post-order walk * for example 5,7,6,9,11,10,8 is true,7,4,6,5 is not * From f7cdbe1325390fb38214a1b2ef7276c183865cc2 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 10 Apr 2017 14:07:14 +0800 Subject: [PATCH 75/96] add coins and knapsack --- .../wcong/test/algorithm/dp/CoinsCollect.java | 27 +++++++++++++++ .../org/wcong/test/algorithm/dp/Knapsack.java | 33 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java create mode 100644 src/main/java/org/wcong/test/algorithm/dp/Knapsack.java diff --git a/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java b/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java new file mode 100644 index 0000000..031c94d --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java @@ -0,0 +1,27 @@ +package org.wcong.test.algorithm.dp; + +/** + * give a m*n matrix board each cell is 0 cell or 1 cell, + * a robot collect coin from left up + * calculate the max coin number when he arrive the right bottom + * + * @author wcong + * @since 2017/4/9 + */ +public class CoinsCollect { + + public static void main(String[] args) { + + } + + public static int maxCoins(int[][] board) { + int[][] result = new int[board.length + 1][board[0].length + 1]; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + result[i + 1][j + 1] = Math.max(result[i][j + 1], result[i + 1][j]) + board[i][j]; + } + } + return result[board.length][board[0].length]; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java b/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java new file mode 100644 index 0000000..a572e28 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java @@ -0,0 +1,33 @@ +package org.wcong.test.algorithm.dp; + +/** + * give n items has weight,w1,w2....,wn and values v1,v2....vn, + * we have a bag contains m weight + * find the largest value for the bag + * + * @author wcong + * @since 2017/4/9 + */ +public class Knapsack { + + public static void main(String[] args) { + + } + + public static int maxValue(int[] weight, int[] values, int bag) { + int[] result = new int[bag + 1]; + result[0] = 0; + for (int i = 1; i <= bag; i++) { + int max = Integer.MIN_VALUE; + for (int j = 0; j < weight.length; j++) { + if (i < weight[j]) { + break; + } + max = Math.max(values[j] + result[i - weight[j]], max); + } + result[i] = max; + } + return result[bag]; + } + +} From 9d3c4811e9cdc506ca069baa0cdfabd28c2fbabf Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 10 Apr 2017 15:31:00 +0800 Subject: [PATCH 76/96] add isSubTree --- .../algorithm/jzoffer/tree/IsSubTree.java | 63 +++++++++++-------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java index 1afc1b9..85c0b9d 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java @@ -13,31 +13,42 @@ */ public class IsSubTree { - public static void main(String[] args) { - - } - - public static boolean isSubTree(Tree tree, Tree subTree) { - if (tree == null || tree.root == null || subTree == null || subTree.root == null) { - return false; - } - TreeNode subNode = subTree.root; - TreeNode fromNode = findSameNode(tree.root, subNode); - return false; - } - - public static TreeNode findSameNode(TreeNode node, TreeNode example) { - if (node == null || example == null) { - return null; - } - if (node.value == example.value) { - return node; - } - TreeNode leftResult = findSameNode(node.left, example); - if (leftResult != null) { - return leftResult; - } - return findSameNode(node.right, example); - } + public static void main(String[] args) { + + } + + public static boolean isSubTree(Tree tree, Tree subTree) { + if (tree == null || tree.root == null || subTree == null || subTree.root == null) { + return false; + } + TreeNode subNode = subTree.root; + return isSubTree(tree.root, subNode); + } + + public static boolean isSubTree(TreeNode node, TreeNode example) { + if (example == null || node == null) { + return false; + } + if (node.value == example.value) { + if (isContainTree(node, example)) { + return true; + } + } + boolean isSub = isSubTree(node.left, example); + return isSub || isSubTree(node.right, example); + } + + private static boolean isContainTree(TreeNode node, TreeNode example) { + if (example == null) { + return true; + } + if (node == null) { + return false; + } + if (node.value == example.value && isContainTree(node.left, example.left) && isContainTree(node.right, example.right)) { + return true; + } + return false; + } } From 4026bfde946ba667a5e4b321890e3c48de304003 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 17 Apr 2017 15:25:07 +0800 Subject: [PATCH 77/96] misc something --- .../cracking/FirstCommonAncestor.java | 50 +++++++++++++++++++ .../test/algorithm/cracking/Successor.java | 30 +++++++++++ .../test/algorithm/cracking/ValidateBST.java | 46 +++++++++++++++++ .../wcong/test/algorithm/tree/BinaryTree.java | 6 +-- 4 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/Successor.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java diff --git a/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java b/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java new file mode 100644 index 0000000..8e64d51 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java @@ -0,0 +1,50 @@ +package org.wcong.test.algorithm.cracking; + +import org.wcong.test.algorithm.tree.BinaryTree; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by wcong on 2017/4/14. + */ +public class FirstCommonAncestor { + + public static void main(String[] args) { + + } + + public static BinaryTree.Node firstCommonAncestor(BinaryTree.Node root, BinaryTree.Node target1, BinaryTree.Node target2) { + List> resultList = new ArrayList<>(2); + List trace = new LinkedList<>(); + firstCommonAncestor(root, target1, target2, resultList, trace); + List pathOne = resultList.get(0); + List pathTwo = resultList.get(1); + return null; + } + + private static void firstCommonAncestor(BinaryTree.Node root, + BinaryTree.Node target1, + BinaryTree.Node target2, + List> resultList, + List trace) { + if (resultList.size() == 2) { + return; + } + trace.add(root); + if (target1.key == root.key) { + resultList.add(new LinkedList<>(trace)); + } else if (target2.key == root.key) { + resultList.add(new LinkedList<>(trace)); + } + if (root.left != null) { + firstCommonAncestor(root.left, target1, target2, resultList, trace); + } + if (root.right != null) { + firstCommonAncestor(root.right, target1, target2, resultList, trace); + } + trace.remove(trace.size() - 1); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/Successor.java b/src/main/java/org/wcong/test/algorithm/cracking/Successor.java new file mode 100644 index 0000000..59267ba --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/Successor.java @@ -0,0 +1,30 @@ +package org.wcong.test.algorithm.cracking; + +import org.wcong.test.algorithm.tree.BinaryTree; + +/** + * Created by wcong on 2017/4/14. + */ +public class Successor { + + public static void main(String[] args) { + + } + + public static BinaryTree.Node successor(BinaryTree.Node root, BinaryTree.Node target) { + if (root == null || target == null) { + return null; + } + BinaryTree.Node successor = null; + while (root != null) { + if (target.key < root.key) { + successor = root; + root = root.left; + } else { + root = root.right; + } + } + return successor; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java b/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java new file mode 100644 index 0000000..7492b75 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java @@ -0,0 +1,46 @@ +package org.wcong.test.algorithm.cracking; + +import org.wcong.test.algorithm.tree.BinaryTree; + +/** + * Created by wcong on 2017/4/14. + */ +public class ValidateBST { + + public static void main(String[] args) { + + } + + static class Result { + boolean validate = true; + int maxForNow = Integer.MIN_VALUE; + } + + public static boolean validate(BinaryTree.Node root) { + if (root == null) { + return true; + } + Result result = new Result(); + validate(root, result); + return result.validate; + } + + public static void validate(BinaryTree.Node root, Result result) { + if (root == null) { + return; + } + if (root.left != null) { + validate(root.left, result); + } + if (!result.validate) { + return; + } + if (result.maxForNow > root.key) { + result.validate = false; + return; + } + result.maxForNow = root.key; + validate(root.right, result); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java index 0487ab1..2adafaa 100644 --- a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java @@ -14,11 +14,11 @@ public Node(int key) { this.key = key; } - int key; + public int key; - Node left; + public Node left; - Node right; + public Node right; } From 33d2a5afe027b6298f8810f6939b707010ff9095 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 17 Apr 2017 18:54:39 +0800 Subject: [PATCH 78/96] rearrange file --- .../array_and_string/CheckPermutation.java | 19 +++++++++++ .../cracking/array_and_string/IsUnique.java | 34 +++++++++++++++++++ .../PalindromePermutation.java | 21 ++++++++++++ .../cracking/array_and_string/URLify.java | 12 +++++++ .../cracking/linked_list/SumList.java | 13 +++++++ .../{ => array}/CountInSortedArray.java | 2 +- .../{ => array}/FindInTwoDimension.java | 2 +- .../jzoffer/{ => array}/MaxSumSubArray.java | 2 +- .../jzoffer/{ => array}/MinKNum.java | 2 +- .../{ => array}/MinNumInRotateArray.java | 2 +- .../{ => array}/MoreThanHalfInArray.java | 2 +- .../{ => array}/ReArrangeOddAndEven.java | 2 +- .../jzoffer/{ => array}/ReplaceBlank.java | 2 +- .../{ => array}/ReverseOrderPareInArray.java | 2 +- .../{ => array}/SortedArraySumTarget.java | 2 +- .../SortedArraySumTargetSubSerial.java | 2 +- .../jzoffer/{ => binary}/Count1InInt.java | 2 +- .../{ => binary}/TwoDifferentNumInArray.java | 2 +- .../algorithm/jzoffer/{ => dp}/Fibonacci.java | 2 +- .../jzoffer/{ => dp}/NumberOf1BeforeN.java | 2 +- .../jzoffer/{ => dp}/UglyNumber.java | 2 +- .../CommonNodeInTwoLinkedList.java | 2 +- .../ComplexListNodeCopy.java | 2 +- .../{ => linked_list}/DeleteNodeInO1.java | 2 +- .../LastKNodeInLinkedList.java | 2 +- .../MergeTwoSortedLinkedList.java | 2 +- .../PrintLinkedListFromBottom.java | 2 +- .../{ => linked_list}/ReversLinkedList.java | 2 +- .../jzoffer/{ => stack}/O1MinStack.java | 2 +- .../jzoffer/{ => stack}/StackPushPopRule.java | 2 +- .../jzoffer/{ => stack}/TwoStackForQueue.java | 2 +- 31 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/CountInSortedArray.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/FindInTwoDimension.java (98%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/MaxSumSubArray.java (94%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/MinKNum.java (98%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/MinNumInRotateArray.java (97%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/MoreThanHalfInArray.java (93%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/ReArrangeOddAndEven.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/ReplaceBlank.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/ReverseOrderPareInArray.java (97%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/SortedArraySumTarget.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => array}/SortedArraySumTargetSubSerial.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => binary}/Count1InInt.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => binary}/TwoDifferentNumInArray.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => dp}/Fibonacci.java (93%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => dp}/NumberOf1BeforeN.java (97%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => dp}/UglyNumber.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/CommonNodeInTwoLinkedList.java (97%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/ComplexListNodeCopy.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/DeleteNodeInO1.java (93%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/LastKNodeInLinkedList.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/MergeTwoSortedLinkedList.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/PrintLinkedListFromBottom.java (84%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => linked_list}/ReversLinkedList.java (95%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => stack}/O1MinStack.java (92%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => stack}/StackPushPopRule.java (96%) rename src/main/java/org/wcong/test/algorithm/jzoffer/{ => stack}/TwoStackForQueue.java (95%) diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java new file mode 100644 index 0000000..48eba4f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java @@ -0,0 +1,19 @@ +package org.wcong.test.algorithm.cracking.array_and_string; + +/** + * give two string write a method to decide if one is permutation of the other + * + * @author wcong + * @since 17/04/2017 + */ +public class CheckPermutation { + + public static void main(String[] args) { + + } + + public static boolean checkPermutation(String a, String b) { + return false; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java new file mode 100644 index 0000000..dd16667 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java @@ -0,0 +1,34 @@ +package org.wcong.test.algorithm.cracking.array_and_string; + +import java.util.HashMap; +import java.util.Map; + +/** + * implement an algorithm to determine if a string has all unique characters + * what if you cannot use additional data structures + *

+ * 1. none additional space and cannot change original string O(n2) + * 2. none additional space and can change original string O(n log n) + * 3. additional space hashMap and O(n) + * + * @author wcong + * @since 17/04/2017 + */ +public class IsUnique { + + public static void main(String[] args) { + + } + + public boolean isUnique(String string) { + Map count = new HashMap<>(); + for (char inner : string.toCharArray()) { + if (count.containsKey(inner)) { + return false; + } + count.put(inner, 1); + } + return true; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java new file mode 100644 index 0000000..c1bd454 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java @@ -0,0 +1,21 @@ +package org.wcong.test.algorithm.cracking.array_and_string; + +/** + * give a string write a function to check if it is a permutation of a palindrome + * a palindrome is a word phrase that has same forward and backward + * a permutation is a rearrangement of letters + * the palindrome does not need to be limit to just dictionary word + * + * key only one odd word + * 1. hash map count the appearance + * 2. binary operate, all exclusive or find the left num,second time,exclusive or other the last result + * @author wcong + * @since 17/04/2017 + */ +public class PalindromePermutation { + + public static void main(String[] args){ + int b = ~1; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java new file mode 100644 index 0000000..611ab23 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java @@ -0,0 +1,12 @@ +package org.wcong.test.algorithm.cracking.array_and_string; + +/** + * Write a method to replace all spaces in a string with '%20 + * You may assume that the string has sufficient space at the end to hold the additional characters + * and that you are given the "true" length of the string. + * (Note: If implementing in Java,please use a character array so that you can perform this operation in place.) + * @author wcong + * @since 17/04/2017 + */ +public class URLify { +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java new file mode 100644 index 0000000..2789ad8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java @@ -0,0 +1,13 @@ +package org.wcong.test.algorithm.cracking.linked_list; + +/** + * @author wcong + * @since 17/04/2017 + */ +public class SumList { + + public static void main(String[] args) { + + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java index d57ecba..5b89776 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/CountInSortedArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; /** * test for array and binary search diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java similarity index 98% rename from src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java index 121cb43..fca9bc8 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/FindInTwoDimension.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java similarity index 94% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java index bd882da..13f994e 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MaxSumSubArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java similarity index 98% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java index 8ad0f9c..7fdd46c 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MinKNum.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import java.util.Arrays; import java.util.Comparator; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java similarity index 97% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java index d9917c5..2663ba4 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MinNumInRotateArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java similarity index 93% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java index 54f333b..27c4731 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MoreThanHalfInArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.eclipse.core.runtime.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java index c1c19f7..1400cdf 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ReArrangeOddAndEven.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java index 45119b8..6fa32b6 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ReplaceBlank.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java similarity index 97% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java index ad55de3..593355f 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ReverseOrderPareInArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java index c323b1e..56d7737 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTarget.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java index 9f72d5c..c7cb336 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/SortedArraySumTargetSubSerial.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.array; import java.util.Arrays; import java.util.LinkedList; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java index 04d43e4..bcf53b2 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/Count1InInt.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.binary; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java index b92f87d..9727f89 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoDifferentNumInArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.binary; /** * test for bit operation and array diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java similarity index 93% rename from src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java index 603bfc7..78f0af3 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/Fibonacci.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.dp; import org.eclipse.core.runtime.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java similarity index 97% rename from src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java index 15697e4..8374983 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/NumberOf1BeforeN.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.dp; import org.eclipse.core.runtime.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java index ef974a4..2990190 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/UglyNumber.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.dp; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java similarity index 97% rename from src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java index 21d16ef..fd819a0 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/CommonNodeInTwoLinkedList.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.springframework.util.Assert; import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java index ebeca0c..c0cd72e 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ComplexListNodeCopy.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.wcong.test.algorithm.jzoffer.util.ComplexListNode; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java similarity index 93% rename from src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java index 630966b..699a10e 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/DeleteNodeInO1.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java index cd9e40c..c9cbb69 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/LastKNodeInLinkedList.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.springframework.util.Assert; import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java index 221f38d..993407b 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/MergeTwoSortedLinkedList.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.springframework.util.Assert; import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java similarity index 84% rename from src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java index 6565006..ef811f9 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintLinkedListFromBottom.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import java.util.List; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java index 98e5d7a..bcb9eab 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/ReversLinkedList.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.linked_list; import org.springframework.util.Assert; import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java similarity index 92% rename from src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java index b1432d5..8b06936 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/O1MinStack.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.stack; import java.util.Stack; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java index 4f71cfc..9ed9d5f 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/StackPushPopRule.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.stack; import org.springframework.util.Assert; diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java similarity index 95% rename from src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java rename to src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java index 96e5e9b..2d66d92 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/TwoStackForQueue.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.jzoffer; +package org.wcong.test.algorithm.jzoffer.stack; import org.springframework.util.Assert; From 31bcacbae7d4d5c646aff6c0616191e960a4ac19 Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 17 Apr 2017 21:02:57 +0800 Subject: [PATCH 79/96] add list --- src/main/java/org/wcong/App.java | 5 +- .../test/algorithm/basic/LinkedList.java | 22 +++++++ .../cracking/linked_list/DeleteMiddle.java | 36 ++++++++++++ .../cracking/linked_list/LoopDetection.java | 44 ++++++++++++++ .../cracking/linked_list/Palindrome.java | 57 +++++++++++++++++++ .../jzoffer/array/CountInSortedArray.java | 2 +- 6 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/basic/LinkedList.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index 4465bf7..49e6332 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -16,10 +16,7 @@ public class App { static int a; public static void main(String[] args) { - DateFormat format = new SimpleDateFormat("M月d日"); - System.out.println(format.format(new Date(2011,11,2))); - System.out.println(format.format(new Date(2011,0,12))); - System.out.println(format.format(new Date(2011,3,12))); + System.out.println(3/2); } public static Class findSuperClassParameterType(Object instance, int parameterIndex) { diff --git a/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java b/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java new file mode 100644 index 0000000..880d73f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java @@ -0,0 +1,22 @@ +package org.wcong.test.algorithm.basic; + +/** + * @author wcong + * @since 17/04/2017 + */ +public class LinkedList { + + public Node root; + + public static class Node { + + public int value; + + public Node next; + + public String toString() { + return String.valueOf(value); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java new file mode 100644 index 0000000..6f6d587 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java @@ -0,0 +1,36 @@ +package org.wcong.test.algorithm.cracking.linked_list; + +import org.wcong.test.algorithm.basic.LinkedList; + +/** + * give a linked list delete the middle node of it + * + * @author wcong + * @since 17/04/2017 + */ +public class DeleteMiddle { + + public static void main(String[] args) { + + } + + public static void deleteMiddle(LinkedList.Node root) { + if (root == null) { + return; + } + LinkedList.Node current = root; + LinkedList.Node middle = root; + int middleCount = 1; + int count = 0; + while (current != null) { + count += 1; + current = current.next; + while (middleCount < (count / 2)) { + middle = middle.next; + middleCount += 1; + } + } + middle.next = middle.next.next; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java new file mode 100644 index 0000000..d638543 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java @@ -0,0 +1,44 @@ +package org.wcong.test.algorithm.cracking.linked_list; + +import org.wcong.test.algorithm.basic.LinkedList; + +/** + * given a circle linked list + * implement an algorithm that return the node at the beginning of the loop + * + * @author wcong + * @since 17/04/2017 + */ +public class LoopDetection { + + public static void main(String[] args) { + + } + + public static LinkedList.Node begining(LinkedList.Node list) { + LinkedList.Node step1 = list; + LinkedList.Node step2 = list; + while (true) { + if (step1 == null || step2 == null) { + return null; + } + step1 = step1.next; + if (step2.next == null) { + return null; + } + step2 = step2.next.next; + if (step1 == step2) { + break; + } + } + step1 = list; + while (true) { + if (step1 == step2) { + return step1; + } + step1 = step1.next; + step2 = step2.next; + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java new file mode 100644 index 0000000..b0e2bad --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java @@ -0,0 +1,57 @@ +package org.wcong.test.algorithm.cracking.linked_list; + +import org.wcong.test.algorithm.basic.LinkedList; + +/** + * implement a function to check if a linked list is palindrome + * + * @author wcong + * @since 17/04/2017 + */ +public class Palindrome { + + public static void main(String[] args) { + + } + + static class Result { + LinkedList.Node node; + + boolean result = true; + + } + + public static boolean isPalindrome(LinkedList.Node root) { + int length = length(root); + return true; + } + + private static Result judge(LinkedList.Node node, int length) { + if (length <= 0) { + Result result = new Result(); + result.node = node.next; + return result; + } else if (length == 1) { + Result result = new Result(); + result.node = node; + return result; + } + Result result = judge(node, length - 2); + if (!result.result) { + return result; + } + result.result = node.value == result.node.value; + result.node = node.next; + return result; + } + + public static int length(LinkedList.Node root) { + int length = 0; + while (root != null) { + length += 1; + root = root.next; + } + return length; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java index 5b89776..47d854b 100644 --- a/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java +++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java @@ -3,7 +3,7 @@ /** * test for array and binary search * give a sorted array count the target appear num - * Created by hzwangcong on 2017/3/28. + * Created by wcong on 2017/3/28. */ public class CountInSortedArray { From 6fec20e48470288b110b6439e361fada7e3f41d9 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 19 Apr 2017 10:21:34 +0800 Subject: [PATCH 80/96] add PathWithSum --- .../org/wcong/test/algorithm/BinaryTree.java | 8 +-- .../cracking/graph/BinarySequences.java | 53 ++++++++++++++++++ .../algorithm/cracking/graph/BuildOrder.java | 18 ++++++ .../cracking/graph/FirstCommonAncestor.java | 55 +++++++++++++++++++ .../algorithm/cracking/graph/PathWithSum.java | 48 ++++++++++++++++ 5 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java diff --git a/src/main/java/org/wcong/test/algorithm/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/BinaryTree.java index 0eeb70f..04ad07b 100644 --- a/src/main/java/org/wcong/test/algorithm/BinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/BinaryTree.java @@ -81,11 +81,11 @@ private void recurrentLink( Node parentNode,DubboLinkedInt parentInt ){ } } - static class Node { - int value; + public static class Node { + public int value; - Node left; + public Node left; - Node right; + public Node right; } } diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java new file mode 100644 index 0000000..836fa61 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java @@ -0,0 +1,53 @@ +package org.wcong.test.algorithm.cracking.graph; + +import org.wcong.test.algorithm.BinaryTree; + +import java.util.LinkedList; +import java.util.List; + +/** + * give a binary search tree with distinct elements + * print all possible arrays that could led to this tree + * + * @author wcong + * @since 18/04/2017 + */ +public class BinarySequences { + + public static void main(String[] args) { + + } + + public static List> sequences(BinaryTree.Node root) { + List> result = new LinkedList<>(); + List path = new LinkedList<>(); + List nextList = new LinkedList<>(); + nextList.add(root); + sequences(nextList, path, result); + return result; + } + + private static void sequences(List nextList, List path, + List> result) { + if (nextList.isEmpty()) { + result.add(path); + return; + } + int i = 0; + for (BinaryTree.Node next : nextList) { + List soloPath = new LinkedList<>(path); + path.add(next); + List nextNextList = new LinkedList<>(nextList); + nextNextList.remove(i); + if (next.left != null) { + nextNextList.add(next.left); + } + if (next.right != null) { + nextNextList.add(next.right); + } + sequences(nextNextList, soloPath, result); + i += 1; + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java new file mode 100644 index 0000000..9d930b2 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java @@ -0,0 +1,18 @@ +package org.wcong.test.algorithm.cracking.graph; + +/** + * give a list of project and a list of dependencies(where a list of pairs of project where the second project dependent on the first project) + * all the project's dependencies must be built for the project is + * find a build order that will build order that allow the projects to be built + * if there is no valid order ,return an error + * + * @author wcong + * @since 18/04/2017 + */ +public class BuildOrder { + + public static void main(String[] args) { + + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java new file mode 100644 index 0000000..e660c88 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java @@ -0,0 +1,55 @@ +package org.wcong.test.algorithm.cracking.graph; + +import org.wcong.test.algorithm.BinaryTree; + +/** + * design a algorithm and write code to + * find the first common ancestor of two nodes in a binary tree, + * avoid store additional node in data structure + * 1. has parent link ,it's like two linked list intersection + * 2. no parent link like tree traversal + * + * @author wcong + * @since 18/04/2017 + */ +public class FirstCommonAncestor { + + public static void main(String[] args) { + } + + static class Result { + BinaryTree.Node node; + + boolean isAncestor; + + public Result(BinaryTree.Node node, boolean isAncestor) { + this.node = node; + this.isAncestor = isAncestor; + } + } + + public static Result firstCommonAncestor(BinaryTree.Node root, BinaryTree.Node node1, BinaryTree.Node node2) { + if (root == null) { + return new Result(null, false); + } + if (root.value == node1.value && root.value == node2.value) { + return new Result(root, false); + } + Result left = firstCommonAncestor(root.left, node1, node2); + if (left.isAncestor) { + return left; + } + Result right = firstCommonAncestor(root.right, node1, node2); + if (right.isAncestor) { + return right; + } + if (left.node != null && right.node != null) { + return new Result(root, true); + } else if (root.value == node1.value || root.value == node2.value) { + boolean isAncestor = left.node != null || right.node != null; + return new Result(root, isAncestor); + } else { + return new Result(null, false); + } + } +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java new file mode 100644 index 0000000..4a7c14e --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java @@ -0,0 +1,48 @@ +package org.wcong.test.algorithm.cracking.graph; + +import org.wcong.test.algorithm.BinaryTree; + +import java.util.HashMap; +import java.util.Map; + +/** + * you are given a binary tree which every node contains an integer value(positive or negative) + * design an algorithm to count the numbers of path that sum to a given value + * the path does need to start or end at the root or leaf but it must go downwards + * depth first traversal, it can be solved by a algorithm for count subList sum to a target + * + * @author wcong + * @since 18/04/2017 + */ +public class PathWithSum { + + public static void main(String[] args) { + + } + + public static int count(BinaryTree.Node root, int target) { + return count(root, 0, target, new HashMap()); + } + + private static int count(BinaryTree.Node root, int sum, int target, Map sumMap) { + if (root == null) { + return 0; + } + sum += root.value; + int left = target - sum; + Integer leftNum = sumMap.get(left); + leftNum = leftNum == null ? 0 : leftNum; + int count = leftNum; + if (sum == target) { + count += 1; + } + + sumMap.put(sum, sumMap.get(sum) == null ? 1 : sumMap.get(sum) + 1); + + int leftCount = count(root.left, sum, target, sumMap); + int rightCount = count(root.right, sum, target, sumMap); + sumMap.put(sum, sumMap.get(sum) - 1); + return count + leftCount + rightCount; + } + +} From 0b54c7ccfbc0899539cc9b95353a0fc5a6b7e323 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 19 Apr 2017 11:14:48 +0800 Subject: [PATCH 81/96] add GroupAnagrams --- .../sort_and_search/GroupAnagrams.java | 45 +++++++++++++++++++ .../cracking/sort_and_search/MergeSorted.java | 42 +++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java new file mode 100644 index 0000000..b884e43 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java @@ -0,0 +1,45 @@ +package org.wcong.test.algorithm.cracking.sort_and_search; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * write a method to sort an array of strings so that all the anagrams are next to each other + * + * @author wcong + * @since 19/04/2017 + */ +public class GroupAnagrams { + + public static void main(String[] args) { + + } + + public static String[] groupAnagrams(String[] array) { + Map> map = new HashMap<>(); + for (String solo : array) { + char[] charArray = solo.toCharArray(); + Arrays.sort(charArray); + String sortedArray = new String(charArray); + List stringList = map.get(sortedArray); + if (stringList == null) { + stringList = new LinkedList<>(); + map.put(sortedArray, stringList); + } + stringList.add(solo); + } + String[] anagrams = new String[array.length]; + int index = 0; + for (List stringList : map.values()) { + for (String solo : stringList) { + anagrams[index] = solo; + index += 1; + } + } + return anagrams; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java new file mode 100644 index 0000000..89d6a22 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java @@ -0,0 +1,42 @@ +package org.wcong.test.algorithm.cracking.sort_and_search; + +/** + * you are given two sorted arrays A and B + * where A has a large enough buffer at the end to hold b + * write a method merge B into A in sorted order + * + * @author wcong + * @since 19/04/2017 + */ +public class MergeSorted { + + public static void main(String[] args) { + + } + + public static void merge(int[] array1, int[] array2) { + int length = array1.length + array2.length; + int array1Index = array1.length - 1; + int array2Index = array2.length - 1; + for (int j = length - 1; j >= 0; j--) { + if (array1Index < 0 && array2Index < 0) { + break; + } else if (array1Index < 0) { + array1[j] = array2[array2Index]; + array2Index -= 1; + } else if (array2Index < 0) { + array1[j] = array1[array1Index]; + array1Index -= 1; + } else { + if (array1[array1Index] < array2[array2Index]) { + array1[j] = array2[array2Index]; + array2Index -= 1; + } else { + array1[j] = array1[array1Index]; + array1Index -= 1; + } + } + } + } + +} From cff157d12791e40f399bf2c090049fc9b5ee4c55 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 19 Apr 2017 15:00:22 +0800 Subject: [PATCH 82/96] add RobotInGrid --- .../algorithm/cracking/dp/MagicIndex.java | 17 +++++ .../algorithm/cracking/dp/RobotInGrid.java | 65 +++++++++++++++++++ .../algorithm/cracking/dp/TripleStep.java | 12 ++++ .../sort_and_search/SparseSearch.java | 42 ++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java b/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java new file mode 100644 index 0000000..d197f99 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java @@ -0,0 +1,17 @@ +package org.wcong.test.algorithm.cracking.dp; + +/** + * a magic index in an array A[1....n-1] is defined to be index such that A[i]=i + * given a sorted array of distinct integers + * write a method to find the magic index,if one exist in array a + * + * @author wcong + * @since 19/04/2017 + */ +public class MagicIndex { + + public int magicIndex(int[] array) { + + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java b/src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java new file mode 100644 index 0000000..8880246 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java @@ -0,0 +1,65 @@ +package org.wcong.test.algorithm.cracking.dp; + +import java.util.LinkedList; +import java.util.List; + +/** + * imagine a robot sitting on the upper left corner of grid with r rows,and c columns + * the robot can move in two directions,right and down + * but certain cells are off limits such that robot cannot step on them + * design an algorithm to find the path for the robot from top left to bottom right + * + * @author wcong + * @since 19/04/2017 + */ +public class RobotInGrid { + + static class Step { + int x; + + int y; + + public Step(int x, int y) { + this.x = x; + this.y = y; + } + } + + public List findPath(int[][] grid) { + + Step[][] step = new Step[grid.length][grid[0].length]; + step[0][grid[0].length - 1] = new Step(0, 0); + for (int y = grid[0].length - 2; y >= 0; y--) { + if (step[0][y + 1] != null && grid[0][y] == 1) { + step[0][y] = new Step(0, y + 1); + } + } + for (int x = 1; x < grid.length; x++) { + if (step[x - 1][grid[0].length - 1] != null && grid[x][grid[0].length - 1] == 1) { + step[x][grid[0].length - 1] = new Step(x - 1, grid[0].length - 1); + } + } + for (int x = 1; x < grid.length; x++) { + for (int y = grid[0].length - 2; y >= 0; y--) { + if (grid[x][y] == 0) { + continue; + } + if (step[x - 1][y] != null) { + step[x][y] = new Step(x - 1, y); + } else if (step[x][y + 1] != null) { + step[x][y] = new Step(x, y + 1); + } + } + } + if (step[grid.length - 1][grid[0].length - 1] == null) { + return null; + } + List findStep = new LinkedList<>(); + Step soloStep = step[grid.length - 1][grid[0].length - 1]; + while (soloStep != null && soloStep.x != 0 && soloStep.y != 0) { + findStep.add(0, soloStep); + soloStep = step[soloStep.x][soloStep.y]; + } + return findStep; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java b/src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java new file mode 100644 index 0000000..cd3c033 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java @@ -0,0 +1,12 @@ +package org.wcong.test.algorithm.cracking.dp; + +/** + * + * @author wcong + * @since 19/04/2017 + */ +public class TripleStep { + + + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java new file mode 100644 index 0000000..41371b2 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java @@ -0,0 +1,42 @@ +package org.wcong.test.algorithm.cracking.sort_and_search; + +/** + * given a sorted array of string that is interspersed with empty string + * write a method to find the location of the string + * + * @author wcong + * @since 19/04/2017 + */ +public class SparseSearch { + + public static void main(String[] args) { + + } + + public static int index(String[] array, String target) { + return index(array, target, 0, array.length); + } + + private static int index(String[] array, String target, int start, int end) { + if (start > end) { + return -1; + } + int middle = start + (end - start) / 2; + if (array[middle].length() == 0) { + int leftIndex = index(array, target, start, middle - 1); + if (leftIndex > 0) { + return leftIndex; + } + return index(array, target, middle + 1, end); + } else { + if (target.equals(array[middle])) { + return middle; + } else if (target.compareTo(array[middle]) < 0) { + return index(array, target, start, middle - 1); + } else { + return index(array, target, middle + 1, end); + } + } + } + +} From ac7bfd8ee5af5df09f3f4fe58dc9b7ad1dd1bc1e Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 19 Apr 2017 16:28:51 +0800 Subject: [PATCH 83/96] add PermutionsWithDuplicates --- .../algorithm/cracking/dp/MagicIndex.java | 17 ----- .../cracking/dp_divide_conque/MagicIndex.java | 42 +++++++++++++ .../dp_divide_conque/Parenthesis.java | 41 ++++++++++++ .../PermutionsWithDuplicates.java | 63 +++++++++++++++++++ .../{dp => dp_divide_conque}/RobotInGrid.java | 2 +- .../dp_divide_conque/TowerOfHanoi.java | 8 +++ .../{dp => dp_divide_conque}/TripleStep.java | 2 +- 7 files changed, 156 insertions(+), 19 deletions(-) delete mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java rename src/main/java/org/wcong/test/algorithm/cracking/{dp => dp_divide_conque}/RobotInGrid.java (96%) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java rename src/main/java/org/wcong/test/algorithm/cracking/{dp => dp_divide_conque}/TripleStep.java (63%) diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java b/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java deleted file mode 100644 index d197f99..0000000 --- a/src/main/java/org/wcong/test/algorithm/cracking/dp/MagicIndex.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.wcong.test.algorithm.cracking.dp; - -/** - * a magic index in an array A[1....n-1] is defined to be index such that A[i]=i - * given a sorted array of distinct integers - * write a method to find the magic index,if one exist in array a - * - * @author wcong - * @since 19/04/2017 - */ -public class MagicIndex { - - public int magicIndex(int[] array) { - - } - -} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java new file mode 100644 index 0000000..6827ad0 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java @@ -0,0 +1,42 @@ +package org.wcong.test.algorithm.cracking.dp_divide_conque; + +/** + * a magic index in an array A[1....n-1] is defined to be index such that A[i]=i + * given a sorted array of distinct integers + * write a method to find the magic index,if one exist in array an index + * + * @author wcong + * @since 19/04/2017 + */ +public class MagicIndex { + + public int magicIndexDistinct(int[] array) { + int start = 0, end = array.length - 1; + while (start < end) { + int middle = start + (end - start) / 2; + if (array[middle] == middle) { + return middle; + } else if (array[middle] > middle) { + end = middle - 1; + } else { + start = middle + 1; + } + } + return -1; + } + + public int magicIndexNormal(int[] array) { + int i = 0; + while (i < array.length) { + if (array[i] == i) { + return i; + } else if (array[i] > i) { + i += 1; + } else { + i = array[i] + 1; + } + } + return -1; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java new file mode 100644 index 0000000..b430924 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.cracking.dp_divide_conque; + +import java.util.LinkedList; +import java.util.List; + +/** + * implement an algorithm to print all valid combinations of n pairs of parenthesis + * + * @author wcong + * @since 19/04/2017 + */ +public class Parenthesis { + + public List parenthesis(int n) { + String[] combinations = new String[n + 1]; + combinations[0] = ""; + for (int i = 1; i <= n; i++) { + StringBuilder stringBuilder = new StringBuilder(i * 2); + for (int j = 0; j < i; j++) { + stringBuilder.append("("); + } + for (int j = 0; j < i; j++) { + stringBuilder.append(")"); + } + combinations[i] = stringBuilder.toString(); + } + List result = new LinkedList<>(); + parenthesisCombination(combinations, "", n, result); + return result; + } + + private void parenthesisCombination(String[] combinations, String prefix, int remain, List result) { + if (remain == 0) { + result.add(prefix); + } + for (int i = 1; i <= remain; i++) { + parenthesisCombination(combinations, prefix + combinations[i], remain - 1, result); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java new file mode 100644 index 0000000..ae44d1b --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java @@ -0,0 +1,63 @@ +package org.wcong.test.algorithm.cracking.dp_divide_conque; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * write a method to compute all permutations of a string are not necessarily unique + * but not duplicates + * + * @author wcong + * @since 19/04/2017 + */ +public class PermutionsWithDuplicates { + + static class Summarise { + List singles = new ArrayList<>(); + + List duplicate = new ArrayList<>(); + } + + static class Duplicate { + Character character; + + int count; + + public Duplicate(Character character, int count) { + this.character = character; + this.count = count; + } + } + + public List duplicates(String a) { + Map duplicate = new HashMap<>(); + for (Character character : a.toCharArray()) { + Integer count = duplicate.get(character); + if (count == null) { + duplicate.put(character, 1); + } else { + duplicate.put(character, count + 1); + } + } + List result = new LinkedList<>(); + makePermutations(duplicate, "", a.length(), result); + return result; + } + + private void makePermutations(Map map, String prefix, int remain, List result) { + if (remain == 0) { + result.add(prefix); + return; + } + for (Map.Entry entry : map.entrySet()) { + int count = entry.getValue(); + map.put(entry.getKey(), count - 1); + makePermutations(map, prefix + entry.getKey(), remain - 1, result); + map.put(entry.getKey(), count); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java similarity index 96% rename from src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java rename to src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java index 8880246..874a16d 100644 --- a/src/main/java/org/wcong/test/algorithm/cracking/dp/RobotInGrid.java +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.cracking.dp; +package org.wcong.test.algorithm.cracking.dp_divide_conque; import java.util.LinkedList; import java.util.List; diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java new file mode 100644 index 0000000..03dc1b3 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java @@ -0,0 +1,8 @@ +package org.wcong.test.algorithm.cracking.dp_divide_conque; + +/** + * @author wcong + * @since 19/04/2017 + */ +public class TowerOfHanoi { +} diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java similarity index 63% rename from src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java rename to src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java index cd3c033..873af93 100644 --- a/src/main/java/org/wcong/test/algorithm/cracking/dp/TripleStep.java +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java @@ -1,4 +1,4 @@ -package org.wcong.test.algorithm.cracking.dp; +package org.wcong.test.algorithm.cracking.dp_divide_conque; /** * From b117fd26b61a782bf7b2a3f0c9ab53437da51e5e Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 1 May 2017 12:03:43 +0800 Subject: [PATCH 84/96] add concurrent problem --- pom.xml | 2 +- src/main/java/org/wcong/App.java | 591 ++++++++++-------- .../dp_divide_conque/BooleanEvaluation.java | 21 + .../java/org/wcong/test/concurrent/Basic.java | 63 ++ .../test/concurrent/CountDownLatchThread.java | 27 + .../test/concurrent/CyclicBarrierPrint.java | 38 ++ .../test/concurrent/ExceptionHandler.java | 30 + .../wcong/test/concurrent/PhaserPrint.java | 30 + .../test/concurrent/ProducerAndComsumer.java | 46 ++ .../wcong/test/concurrent/SemaphorePrint.java | 25 + .../test/concurrent/SynchronizedMethod.java | 60 ++ .../org/wcong/test/concurrent/ThreadWait.java | 33 + .../wcong/test/concurrent/ThreadWithStop.java | 27 + .../concurrent/CountDownLatchThreadTest.java | 31 + .../concurrent/CyclicBarrierPrintTest.java | 41 ++ .../test/concurrent/PhaserPrintTest.java | 31 + .../test/concurrent/SemaphorePrintTest.java | 44 ++ .../concurrent/SynchronizedMethodTest.java | 26 + .../test/concurrent/ThreadWithStopTest.java | 31 + .../java/org/wcong/test/package-info.java | 1 + 20 files changed, 953 insertions(+), 245 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java create mode 100644 src/main/java/org/wcong/test/concurrent/Basic.java create mode 100644 src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java create mode 100644 src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java create mode 100644 src/main/java/org/wcong/test/concurrent/ExceptionHandler.java create mode 100644 src/main/java/org/wcong/test/concurrent/PhaserPrint.java create mode 100644 src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java create mode 100644 src/main/java/org/wcong/test/concurrent/SemaphorePrint.java create mode 100644 src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java create mode 100644 src/main/java/org/wcong/test/concurrent/ThreadWait.java create mode 100644 src/main/java/org/wcong/test/concurrent/ThreadWithStop.java create mode 100644 src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java create mode 100644 src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java create mode 100644 src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java create mode 100644 src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java create mode 100644 src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java create mode 100644 src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java create mode 100644 src/test/java/org/wcong/test/package-info.java diff --git a/pom.xml b/pom.xml index b4466ad..b51b888 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ junit junit - 3.8.1 + 4.12 test diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index 49e6332..4c3427a 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -1,255 +1,358 @@ package org.wcong; -import java.lang.reflect.ParameterizedType; -import java.math.BigDecimal; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; + +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; +import java.util.Scanner; /** * Hello world! */ public class App { - static int a; - - public static void main(String[] args) { - System.out.println(3/2); - } - - public static Class findSuperClassParameterType(Object instance, int parameterIndex) { - Class subClass = instance.getClass(); - while (subClass != subClass.getSuperclass()) { - // instance.getClass() is no subclass of classOfInterest or instance is a direct instance of classOfInterest - subClass = subClass.getSuperclass(); - if (subClass == null) throw new IllegalArgumentException(); - } - ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass(); - return (Class) parameterizedType.getActualTypeArguments()[parameterIndex]; - } - - public class A { - } - - public static class B { - } - - - public enum LogisticsCompanyEnum { - - QITA("Q", 0, "其它"), SHUNFENG("S", 1, "顺丰速运"), ZHONGTONG("Z", 2, "中通快递"), SHENTONG("S", 3, "申通快递"), YUANTONG("Y", 4, "圆通快递"), YUNDA("Y", 5, "韵达快递"), - EMS("E", 6, "EMS"), TIANTIAN("T", 7, "天天快递"), GUOTONG("G", 8, "国通快递"), SUER("S", 9, "速尔快递"), BAISHI("B", 10, "百世汇通"), LIANBANG("L", 11, "联邦快递"), - QUANFENG("Q", 12, "全峰快递"), ZAIJISONG("Z", 13, "宅急送"), QUANYI("Q", 14, "全一快递"), UPS("U", 15, "UPS快递"), - ZHONG_WAI_YUN("Z", 16, "中外运速递"),; - - private String initial; - private int logisticsCompanyId; - private String logisticsCompanyName; - - private LogisticsCompanyEnum(String initial, int logisticsCompanyId, String logisticsCompanyName) { - this.initial = initial; - this.logisticsCompanyId = logisticsCompanyId; - this.logisticsCompanyName = logisticsCompanyName; - } - - public String getInitial() { - return initial; - } - - public int getLogisticsCompanyId() { - return logisticsCompanyId; - } - - public String getLogisticsCompanyName() { - return logisticsCompanyName; - } - - } - - private static final Map ID_TO_NAME_LOGISTICS = new HashMap(); - - static { - ID_TO_NAME_LOGISTICS.put(16L, "中外运速递"); - ID_TO_NAME_LOGISTICS.put(17L, "E特快"); - ID_TO_NAME_LOGISTICS.put(18L, "芝麻开门"); - ID_TO_NAME_LOGISTICS.put(19L, "赛澳递"); - ID_TO_NAME_LOGISTICS.put(20L, "安能物流"); - ID_TO_NAME_LOGISTICS.put(21L, "安迅物流"); - ID_TO_NAME_LOGISTICS.put(22L, "巴伦支快递"); - ID_TO_NAME_LOGISTICS.put(23L, "北青小红帽"); - ID_TO_NAME_LOGISTICS.put(24L, "百福东方物流"); - ID_TO_NAME_LOGISTICS.put(25L, "邦送物流"); - ID_TO_NAME_LOGISTICS.put(26L, "宝凯物流"); - ID_TO_NAME_LOGISTICS.put(27L, "百千诚物流"); - ID_TO_NAME_LOGISTICS.put(28L, "博源恒通"); - ID_TO_NAME_LOGISTICS.put(29L, "百成大达物流"); - ID_TO_NAME_LOGISTICS.put(30L, "百世快运"); - ID_TO_NAME_LOGISTICS.put(31L, "COE(东方快递)"); - ID_TO_NAME_LOGISTICS.put(32L, "城市100"); - ID_TO_NAME_LOGISTICS.put(33L, "传喜物流"); - ID_TO_NAME_LOGISTICS.put(34L, "城际速递"); - ID_TO_NAME_LOGISTICS.put(35L, "成都立即送"); - ID_TO_NAME_LOGISTICS.put(36L, "出口易"); - ID_TO_NAME_LOGISTICS.put(37L, "晟邦物流"); - ID_TO_NAME_LOGISTICS.put(38L, "DHL快递"); - ID_TO_NAME_LOGISTICS.put(39L, "DHL"); - ID_TO_NAME_LOGISTICS.put(40L, "德邦大田物流"); - ID_TO_NAME_LOGISTICS.put(41L, "东方快递"); - ID_TO_NAME_LOGISTICS.put(42L, "递四方"); - ID_TO_NAME_LOGISTICS.put(43L, "大洋物流"); - ID_TO_NAME_LOGISTICS.put(44L, "店通快递"); - ID_TO_NAME_LOGISTICS.put(45L, "德创物流"); - ID_TO_NAME_LOGISTICS.put(46L, "东红物流"); - ID_TO_NAME_LOGISTICS.put(47L, "D速物流"); - ID_TO_NAME_LOGISTICS.put(48L, "东瀚物流"); - ID_TO_NAME_LOGISTICS.put(49L, "达方物流"); - ID_TO_NAME_LOGISTICS.put(50L, "俄顺达"); - ID_TO_NAME_LOGISTICS.put(51L, "FedEx快递"); - ID_TO_NAME_LOGISTICS.put(52L, "飞康达物流"); - ID_TO_NAME_LOGISTICS.put(53L, "飞豹快递"); - ID_TO_NAME_LOGISTICS.put(54L, "飞狐快递"); - ID_TO_NAME_LOGISTICS.put(55L, "凡宇速递"); - ID_TO_NAME_LOGISTICS.put(56L, "颿达国际"); - ID_TO_NAME_LOGISTICS.put(57L, "飞远配送"); - ID_TO_NAME_LOGISTICS.put(58L, "飞鹰物流"); - ID_TO_NAME_LOGISTICS.put(59L, "风行天下"); - ID_TO_NAME_LOGISTICS.put(60L, "GATI快递"); - ID_TO_NAME_LOGISTICS.put(61L, "港中能达物流"); - ID_TO_NAME_LOGISTICS.put(62L, "共速达"); - ID_TO_NAME_LOGISTICS.put(63L, "广通速递"); - ID_TO_NAME_LOGISTICS.put(64L, "广东速腾物流"); - ID_TO_NAME_LOGISTICS.put(65L, "港快速递"); - ID_TO_NAME_LOGISTICS.put(66L, "高铁速递"); - ID_TO_NAME_LOGISTICS.put(67L, "冠达快递"); - ID_TO_NAME_LOGISTICS.put(68L, "华宇物流"); - ID_TO_NAME_LOGISTICS.put(69L, "恒路物流"); - ID_TO_NAME_LOGISTICS.put(70L, "好来运快递"); - ID_TO_NAME_LOGISTICS.put(71L, "华夏龙物流"); - ID_TO_NAME_LOGISTICS.put(72L, "海航天天"); - ID_TO_NAME_LOGISTICS.put(73L, "河北建华"); - ID_TO_NAME_LOGISTICS.put(74L, "海盟速递"); - ID_TO_NAME_LOGISTICS.put(75L, "华企快运"); - ID_TO_NAME_LOGISTICS.put(76L, "昊盛物流"); - ID_TO_NAME_LOGISTICS.put(77L, "户通物流"); - ID_TO_NAME_LOGISTICS.put(78L, "华航快递"); - ID_TO_NAME_LOGISTICS.put(79L, "黄马甲快递"); - ID_TO_NAME_LOGISTICS.put(80L, "合众速递(UCS)"); - ID_TO_NAME_LOGISTICS.put(81L, "韩润物流"); - ID_TO_NAME_LOGISTICS.put(82L, "皇家物流"); - ID_TO_NAME_LOGISTICS.put(83L, "伙伴物流"); - ID_TO_NAME_LOGISTICS.put(84L, "红马速递"); - ID_TO_NAME_LOGISTICS.put(85L, "汇文配送"); - ID_TO_NAME_LOGISTICS.put(86L, "华赫物流"); - ID_TO_NAME_LOGISTICS.put(87L, "佳吉物流"); - ID_TO_NAME_LOGISTICS.put(88L, "佳怡物流"); - ID_TO_NAME_LOGISTICS.put(89L, "加运美快递"); - ID_TO_NAME_LOGISTICS.put(90L, "急先达物流"); - ID_TO_NAME_LOGISTICS.put(91L, "京广速递"); - ID_TO_NAME_LOGISTICS.put(92L, "晋越快递"); - ID_TO_NAME_LOGISTICS.put(93L, "捷特快递"); - ID_TO_NAME_LOGISTICS.put(94L, "久易快递"); - ID_TO_NAME_LOGISTICS.put(95L, "快捷快递"); - ID_TO_NAME_LOGISTICS.put(96L, "康力物流"); - ID_TO_NAME_LOGISTICS.put(97L, "跨越速运"); - ID_TO_NAME_LOGISTICS.put(98L, "快优达速递"); - ID_TO_NAME_LOGISTICS.put(99L, "快淘快递"); - ID_TO_NAME_LOGISTICS.put(100L, "联昊通物流"); - ID_TO_NAME_LOGISTICS.put(101L, "龙邦速递"); - ID_TO_NAME_LOGISTICS.put(102L, "乐捷递"); - ID_TO_NAME_LOGISTICS.put(103L, "立即送"); - ID_TO_NAME_LOGISTICS.put(104L, "蓝弧快递"); - ID_TO_NAME_LOGISTICS.put(105L, "乐天速递"); - ID_TO_NAME_LOGISTICS.put(106L, "民航快递"); - ID_TO_NAME_LOGISTICS.put(107L, "美国快递"); - ID_TO_NAME_LOGISTICS.put(108L, "门对门"); - ID_TO_NAME_LOGISTICS.put(109L, "明亮物流"); - ID_TO_NAME_LOGISTICS.put(110L, "民邦速递"); - ID_TO_NAME_LOGISTICS.put(111L, "闽盛快递"); - ID_TO_NAME_LOGISTICS.put(112L, "麦力快递"); - ID_TO_NAME_LOGISTICS.put(113L, "能达速递"); - ID_TO_NAME_LOGISTICS.put(114L, "偌亚奥国际"); - ID_TO_NAME_LOGISTICS.put(115L, "平安达腾飞"); - ID_TO_NAME_LOGISTICS.put(116L, "陪行物流"); - ID_TO_NAME_LOGISTICS.put(117L, "全日通快递"); - ID_TO_NAME_LOGISTICS.put(118L, "全晨快递"); - ID_TO_NAME_LOGISTICS.put(119L, "秦邦快运"); - ID_TO_NAME_LOGISTICS.put(120L, "如风达快递"); - ID_TO_NAME_LOGISTICS.put(121L, "日昱物流"); - ID_TO_NAME_LOGISTICS.put(122L, "瑞丰速递"); - ID_TO_NAME_LOGISTICS.put(123L, "山东海红"); - ID_TO_NAME_LOGISTICS.put(124L, "盛辉物流"); - ID_TO_NAME_LOGISTICS.put(125L, "世运快递"); - ID_TO_NAME_LOGISTICS.put(126L, "盛丰物流"); - ID_TO_NAME_LOGISTICS.put(127L, "上大物流"); - ID_TO_NAME_LOGISTICS.put(128L, "三态速递"); - ID_TO_NAME_LOGISTICS.put(129L, "申通E物流"); - ID_TO_NAME_LOGISTICS.put(130L, "圣安物流"); - ID_TO_NAME_LOGISTICS.put(131L, "山西红马甲"); - ID_TO_NAME_LOGISTICS.put(132L, "穗佳物流"); - ID_TO_NAME_LOGISTICS.put(133L, "沈阳佳惠尔"); - ID_TO_NAME_LOGISTICS.put(134L, "上海林道货运"); - ID_TO_NAME_LOGISTICS.put(135L, "十方通物流"); - ID_TO_NAME_LOGISTICS.put(136L, "山东广通速递"); - ID_TO_NAME_LOGISTICS.put(137L, "顺捷丰达"); - ID_TO_NAME_LOGISTICS.put(138L, "TTNT快递"); - ID_TO_NAME_LOGISTICS.put(139L, "天地华宇"); - ID_TO_NAME_LOGISTICS.put(140L, "通和天下"); - ID_TO_NAME_LOGISTICS.put(141L, "天纵物流"); - ID_TO_NAME_LOGISTICS.put(142L, "同舟行物流"); - ID_TO_NAME_LOGISTICS.put(143L, "腾达速递"); - ID_TO_NAME_LOGISTICS.put(144L, "UC优速快递"); - ID_TO_NAME_LOGISTICS.put(145L, "万象物流"); - ID_TO_NAME_LOGISTICS.put(146L, "微特派"); - ID_TO_NAME_LOGISTICS.put(147L, "万家物流"); - ID_TO_NAME_LOGISTICS.put(148L, "万博快递"); - ID_TO_NAME_LOGISTICS.put(149L, "希优特快递"); - ID_TO_NAME_LOGISTICS.put(150L, "新邦物流"); - ID_TO_NAME_LOGISTICS.put(151L, "信丰物流"); - ID_TO_NAME_LOGISTICS.put(152L, "祥龙运通物流"); - ID_TO_NAME_LOGISTICS.put(153L, "西安城联速递"); - ID_TO_NAME_LOGISTICS.put(154L, "西安喜来快递"); - ID_TO_NAME_LOGISTICS.put(155L, "鑫世锐达"); - ID_TO_NAME_LOGISTICS.put(156L, "鑫通宝物流"); - ID_TO_NAME_LOGISTICS.put(157L, "运通快递"); - ID_TO_NAME_LOGISTICS.put(158L, "远成物流"); - ID_TO_NAME_LOGISTICS.put(159L, "亚风速递"); - ID_TO_NAME_LOGISTICS.put(160L, "优速快递"); - ID_TO_NAME_LOGISTICS.put(161L, "亿顺航"); - ID_TO_NAME_LOGISTICS.put(162L, "越丰物流"); - ID_TO_NAME_LOGISTICS.put(163L, "源安达快递"); - ID_TO_NAME_LOGISTICS.put(164L, "原飞航物流"); - ID_TO_NAME_LOGISTICS.put(165L, "邮政EMS速递"); - ID_TO_NAME_LOGISTICS.put(166L, "银捷速递"); - ID_TO_NAME_LOGISTICS.put(167L, "一统飞鸿"); - ID_TO_NAME_LOGISTICS.put(168L, "宇鑫物流"); - ID_TO_NAME_LOGISTICS.put(169L, "易通达"); - ID_TO_NAME_LOGISTICS.put(170L, "邮必佳"); - ID_TO_NAME_LOGISTICS.put(171L, "一柒物流"); - ID_TO_NAME_LOGISTICS.put(172L, "音素快运"); - ID_TO_NAME_LOGISTICS.put(173L, "亿领速运"); - ID_TO_NAME_LOGISTICS.put(174L, "煜嘉物流"); - ID_TO_NAME_LOGISTICS.put(175L, "英脉物流"); - ID_TO_NAME_LOGISTICS.put(176L, "云南中诚"); - ID_TO_NAME_LOGISTICS.put(177L, "中铁快运"); - ID_TO_NAME_LOGISTICS.put(178L, "中铁物流"); - ID_TO_NAME_LOGISTICS.put(179L, "中邮物流"); - ID_TO_NAME_LOGISTICS.put(180L, "邮政快递"); - ID_TO_NAME_LOGISTICS.put(181L, "郑州建华"); - ID_TO_NAME_LOGISTICS.put(182L, "中速快件"); - ID_TO_NAME_LOGISTICS.put(183L, "中天万运"); - ID_TO_NAME_LOGISTICS.put(184L, "中睿速递"); - ID_TO_NAME_LOGISTICS.put(185L, "增益速递"); - ID_TO_NAME_LOGISTICS.put(186L, "郑州速捷"); - ID_TO_NAME_LOGISTICS.put(187L, "智通物流"); - -// // 把enum中的最初的标准15个快递公司和其它也加进来 -// LogisticsCompanyEnum[] firstArray = LogisticsCompanyEnum.values(); -// for (int i = 0; i < firstArray.length; i++) { -// ID_TO_NAME_LOGISTICS.put(new Long(firstArray[i].getLogisticsCompanyId()), -// firstArray[i].getLogisticsCompanyName()); -// } - } + static int a; + + static class Node { + int coin; + + int index; + + int sum = 0; + + Node parent; + + int depth = 1; + + List children = new ArrayList<>(); + + public Node(int coin, int index) { + this.coin = coin; + this.index = index; + } + + public static void buildSum(Node node, int depth) { + node.sum = node.coin; + node.depth = depth; + if (!node.children.isEmpty()) { + for (Node childNode : node.children) { + buildSum(childNode, depth + 1); + node.sum += childNode.sum; + } + } + } + } + static String stringGameWinner(String s, String p){ + // Complete this function + boolean amandaWin; + if( s.length() left) { + return first - left; + } + if (second == left && second > first) { + return second - first; + } + if (first == left && first > second) { + return first - second; + } + return -1; + } + + private static void addRecursive(List powerList, int index, int sum, int[] result) { + if (sum >= result.length) { + return; + } + if (index >= powerList.size()) { + result[sum] += 1; + return; + } + addRecursive(powerList, index + 1, sum + powerList.get(index), result); + addRecursive(powerList, index + 1, sum, result); + } + + public class A { + + } + + public static class B { + } + + public enum LogisticsCompanyEnum { + + QITA("Q", 0, "其它"), SHUNFENG("S", 1, "顺丰速运"), ZHONGTONG("Z", 2, "中通快递"), SHENTONG("S", 3, "申通快递"), YUANTONG("Y", + 4, "圆通快递"), YUNDA("Y", 5, "韵达快递"), + EMS("E", 6, "EMS"), TIANTIAN("T", 7, "天天快递"), GUOTONG("G", 8, "国通快递"), SUER("S", 9, "速尔快递"), BAISHI("B", 10, + "百世汇通"), LIANBANG("L", 11, "联邦快递"), + QUANFENG("Q", 12, "全峰快递"), ZAIJISONG("Z", 13, "宅急送"), QUANYI("Q", 14, "全一快递"), UPS("U", 15, "UPS快递"), + ZHONG_WAI_YUN("Z", 16, "中外运速递"),; + + private String initial; + + private int logisticsCompanyId; + + private String logisticsCompanyName; + + private LogisticsCompanyEnum(String initial, int logisticsCompanyId, String logisticsCompanyName) { + this.initial = initial; + this.logisticsCompanyId = logisticsCompanyId; + this.logisticsCompanyName = logisticsCompanyName; + } + + public String getInitial() { + return initial; + } + + public int getLogisticsCompanyId() { + return logisticsCompanyId; + } + + public String getLogisticsCompanyName() { + return logisticsCompanyName; + } + + } + + private static final Map ID_TO_NAME_LOGISTICS = new HashMap(); + + static { + ID_TO_NAME_LOGISTICS.put(16L, "中外运速递"); + ID_TO_NAME_LOGISTICS.put(17L, "E特快"); + ID_TO_NAME_LOGISTICS.put(18L, "芝麻开门"); + ID_TO_NAME_LOGISTICS.put(19L, "赛澳递"); + ID_TO_NAME_LOGISTICS.put(20L, "安能物流"); + ID_TO_NAME_LOGISTICS.put(21L, "安迅物流"); + ID_TO_NAME_LOGISTICS.put(22L, "巴伦支快递"); + ID_TO_NAME_LOGISTICS.put(23L, "北青小红帽"); + ID_TO_NAME_LOGISTICS.put(24L, "百福东方物流"); + ID_TO_NAME_LOGISTICS.put(25L, "邦送物流"); + ID_TO_NAME_LOGISTICS.put(26L, "宝凯物流"); + ID_TO_NAME_LOGISTICS.put(27L, "百千诚物流"); + ID_TO_NAME_LOGISTICS.put(28L, "博源恒通"); + ID_TO_NAME_LOGISTICS.put(29L, "百成大达物流"); + ID_TO_NAME_LOGISTICS.put(30L, "百世快运"); + ID_TO_NAME_LOGISTICS.put(31L, "COE(东方快递)"); + ID_TO_NAME_LOGISTICS.put(32L, "城市100"); + ID_TO_NAME_LOGISTICS.put(33L, "传喜物流"); + ID_TO_NAME_LOGISTICS.put(34L, "城际速递"); + ID_TO_NAME_LOGISTICS.put(35L, "成都立即送"); + ID_TO_NAME_LOGISTICS.put(36L, "出口易"); + ID_TO_NAME_LOGISTICS.put(37L, "晟邦物流"); + ID_TO_NAME_LOGISTICS.put(38L, "DHL快递"); + ID_TO_NAME_LOGISTICS.put(39L, "DHL"); + ID_TO_NAME_LOGISTICS.put(40L, "德邦大田物流"); + ID_TO_NAME_LOGISTICS.put(41L, "东方快递"); + ID_TO_NAME_LOGISTICS.put(42L, "递四方"); + ID_TO_NAME_LOGISTICS.put(43L, "大洋物流"); + ID_TO_NAME_LOGISTICS.put(44L, "店通快递"); + ID_TO_NAME_LOGISTICS.put(45L, "德创物流"); + ID_TO_NAME_LOGISTICS.put(46L, "东红物流"); + ID_TO_NAME_LOGISTICS.put(47L, "D速物流"); + ID_TO_NAME_LOGISTICS.put(48L, "东瀚物流"); + ID_TO_NAME_LOGISTICS.put(49L, "达方物流"); + ID_TO_NAME_LOGISTICS.put(50L, "俄顺达"); + ID_TO_NAME_LOGISTICS.put(51L, "FedEx快递"); + ID_TO_NAME_LOGISTICS.put(52L, "飞康达物流"); + ID_TO_NAME_LOGISTICS.put(53L, "飞豹快递"); + ID_TO_NAME_LOGISTICS.put(54L, "飞狐快递"); + ID_TO_NAME_LOGISTICS.put(55L, "凡宇速递"); + ID_TO_NAME_LOGISTICS.put(56L, "颿达国际"); + ID_TO_NAME_LOGISTICS.put(57L, "飞远配送"); + ID_TO_NAME_LOGISTICS.put(58L, "飞鹰物流"); + ID_TO_NAME_LOGISTICS.put(59L, "风行天下"); + ID_TO_NAME_LOGISTICS.put(60L, "GATI快递"); + ID_TO_NAME_LOGISTICS.put(61L, "港中能达物流"); + ID_TO_NAME_LOGISTICS.put(62L, "共速达"); + ID_TO_NAME_LOGISTICS.put(63L, "广通速递"); + ID_TO_NAME_LOGISTICS.put(64L, "广东速腾物流"); + ID_TO_NAME_LOGISTICS.put(65L, "港快速递"); + ID_TO_NAME_LOGISTICS.put(66L, "高铁速递"); + ID_TO_NAME_LOGISTICS.put(67L, "冠达快递"); + ID_TO_NAME_LOGISTICS.put(68L, "华宇物流"); + ID_TO_NAME_LOGISTICS.put(69L, "恒路物流"); + ID_TO_NAME_LOGISTICS.put(70L, "好来运快递"); + ID_TO_NAME_LOGISTICS.put(71L, "华夏龙物流"); + ID_TO_NAME_LOGISTICS.put(72L, "海航天天"); + ID_TO_NAME_LOGISTICS.put(73L, "河北建华"); + ID_TO_NAME_LOGISTICS.put(74L, "海盟速递"); + ID_TO_NAME_LOGISTICS.put(75L, "华企快运"); + ID_TO_NAME_LOGISTICS.put(76L, "昊盛物流"); + ID_TO_NAME_LOGISTICS.put(77L, "户通物流"); + ID_TO_NAME_LOGISTICS.put(78L, "华航快递"); + ID_TO_NAME_LOGISTICS.put(79L, "黄马甲快递"); + ID_TO_NAME_LOGISTICS.put(80L, "合众速递(UCS)"); + ID_TO_NAME_LOGISTICS.put(81L, "韩润物流"); + ID_TO_NAME_LOGISTICS.put(82L, "皇家物流"); + ID_TO_NAME_LOGISTICS.put(83L, "伙伴物流"); + ID_TO_NAME_LOGISTICS.put(84L, "红马速递"); + ID_TO_NAME_LOGISTICS.put(85L, "汇文配送"); + ID_TO_NAME_LOGISTICS.put(86L, "华赫物流"); + ID_TO_NAME_LOGISTICS.put(87L, "佳吉物流"); + ID_TO_NAME_LOGISTICS.put(88L, "佳怡物流"); + ID_TO_NAME_LOGISTICS.put(89L, "加运美快递"); + ID_TO_NAME_LOGISTICS.put(90L, "急先达物流"); + ID_TO_NAME_LOGISTICS.put(91L, "京广速递"); + ID_TO_NAME_LOGISTICS.put(92L, "晋越快递"); + ID_TO_NAME_LOGISTICS.put(93L, "捷特快递"); + ID_TO_NAME_LOGISTICS.put(94L, "久易快递"); + ID_TO_NAME_LOGISTICS.put(95L, "快捷快递"); + ID_TO_NAME_LOGISTICS.put(96L, "康力物流"); + ID_TO_NAME_LOGISTICS.put(97L, "跨越速运"); + ID_TO_NAME_LOGISTICS.put(98L, "快优达速递"); + ID_TO_NAME_LOGISTICS.put(99L, "快淘快递"); + ID_TO_NAME_LOGISTICS.put(100L, "联昊通物流"); + ID_TO_NAME_LOGISTICS.put(101L, "龙邦速递"); + ID_TO_NAME_LOGISTICS.put(102L, "乐捷递"); + ID_TO_NAME_LOGISTICS.put(103L, "立即送"); + ID_TO_NAME_LOGISTICS.put(104L, "蓝弧快递"); + ID_TO_NAME_LOGISTICS.put(105L, "乐天速递"); + ID_TO_NAME_LOGISTICS.put(106L, "民航快递"); + ID_TO_NAME_LOGISTICS.put(107L, "美国快递"); + ID_TO_NAME_LOGISTICS.put(108L, "门对门"); + ID_TO_NAME_LOGISTICS.put(109L, "明亮物流"); + ID_TO_NAME_LOGISTICS.put(110L, "民邦速递"); + ID_TO_NAME_LOGISTICS.put(111L, "闽盛快递"); + ID_TO_NAME_LOGISTICS.put(112L, "麦力快递"); + ID_TO_NAME_LOGISTICS.put(113L, "能达速递"); + ID_TO_NAME_LOGISTICS.put(114L, "偌亚奥国际"); + ID_TO_NAME_LOGISTICS.put(115L, "平安达腾飞"); + ID_TO_NAME_LOGISTICS.put(116L, "陪行物流"); + ID_TO_NAME_LOGISTICS.put(117L, "全日通快递"); + ID_TO_NAME_LOGISTICS.put(118L, "全晨快递"); + ID_TO_NAME_LOGISTICS.put(119L, "秦邦快运"); + ID_TO_NAME_LOGISTICS.put(120L, "如风达快递"); + ID_TO_NAME_LOGISTICS.put(121L, "日昱物流"); + ID_TO_NAME_LOGISTICS.put(122L, "瑞丰速递"); + ID_TO_NAME_LOGISTICS.put(123L, "山东海红"); + ID_TO_NAME_LOGISTICS.put(124L, "盛辉物流"); + ID_TO_NAME_LOGISTICS.put(125L, "世运快递"); + ID_TO_NAME_LOGISTICS.put(126L, "盛丰物流"); + ID_TO_NAME_LOGISTICS.put(127L, "上大物流"); + ID_TO_NAME_LOGISTICS.put(128L, "三态速递"); + ID_TO_NAME_LOGISTICS.put(129L, "申通E物流"); + ID_TO_NAME_LOGISTICS.put(130L, "圣安物流"); + ID_TO_NAME_LOGISTICS.put(131L, "山西红马甲"); + ID_TO_NAME_LOGISTICS.put(132L, "穗佳物流"); + ID_TO_NAME_LOGISTICS.put(133L, "沈阳佳惠尔"); + ID_TO_NAME_LOGISTICS.put(134L, "上海林道货运"); + ID_TO_NAME_LOGISTICS.put(135L, "十方通物流"); + ID_TO_NAME_LOGISTICS.put(136L, "山东广通速递"); + ID_TO_NAME_LOGISTICS.put(137L, "顺捷丰达"); + ID_TO_NAME_LOGISTICS.put(138L, "TTNT快递"); + ID_TO_NAME_LOGISTICS.put(139L, "天地华宇"); + ID_TO_NAME_LOGISTICS.put(140L, "通和天下"); + ID_TO_NAME_LOGISTICS.put(141L, "天纵物流"); + ID_TO_NAME_LOGISTICS.put(142L, "同舟行物流"); + ID_TO_NAME_LOGISTICS.put(143L, "腾达速递"); + ID_TO_NAME_LOGISTICS.put(144L, "UC优速快递"); + ID_TO_NAME_LOGISTICS.put(145L, "万象物流"); + ID_TO_NAME_LOGISTICS.put(146L, "微特派"); + ID_TO_NAME_LOGISTICS.put(147L, "万家物流"); + ID_TO_NAME_LOGISTICS.put(148L, "万博快递"); + ID_TO_NAME_LOGISTICS.put(149L, "希优特快递"); + ID_TO_NAME_LOGISTICS.put(150L, "新邦物流"); + ID_TO_NAME_LOGISTICS.put(151L, "信丰物流"); + ID_TO_NAME_LOGISTICS.put(152L, "祥龙运通物流"); + ID_TO_NAME_LOGISTICS.put(153L, "西安城联速递"); + ID_TO_NAME_LOGISTICS.put(154L, "西安喜来快递"); + ID_TO_NAME_LOGISTICS.put(155L, "鑫世锐达"); + ID_TO_NAME_LOGISTICS.put(156L, "鑫通宝物流"); + ID_TO_NAME_LOGISTICS.put(157L, "运通快递"); + ID_TO_NAME_LOGISTICS.put(158L, "远成物流"); + ID_TO_NAME_LOGISTICS.put(159L, "亚风速递"); + ID_TO_NAME_LOGISTICS.put(160L, "优速快递"); + ID_TO_NAME_LOGISTICS.put(161L, "亿顺航"); + ID_TO_NAME_LOGISTICS.put(162L, "越丰物流"); + ID_TO_NAME_LOGISTICS.put(163L, "源安达快递"); + ID_TO_NAME_LOGISTICS.put(164L, "原飞航物流"); + ID_TO_NAME_LOGISTICS.put(165L, "邮政EMS速递"); + ID_TO_NAME_LOGISTICS.put(166L, "银捷速递"); + ID_TO_NAME_LOGISTICS.put(167L, "一统飞鸿"); + ID_TO_NAME_LOGISTICS.put(168L, "宇鑫物流"); + ID_TO_NAME_LOGISTICS.put(169L, "易通达"); + ID_TO_NAME_LOGISTICS.put(170L, "邮必佳"); + ID_TO_NAME_LOGISTICS.put(171L, "一柒物流"); + ID_TO_NAME_LOGISTICS.put(172L, "音素快运"); + ID_TO_NAME_LOGISTICS.put(173L, "亿领速运"); + ID_TO_NAME_LOGISTICS.put(174L, "煜嘉物流"); + ID_TO_NAME_LOGISTICS.put(175L, "英脉物流"); + ID_TO_NAME_LOGISTICS.put(176L, "云南中诚"); + ID_TO_NAME_LOGISTICS.put(177L, "中铁快运"); + ID_TO_NAME_LOGISTICS.put(178L, "中铁物流"); + ID_TO_NAME_LOGISTICS.put(179L, "中邮物流"); + ID_TO_NAME_LOGISTICS.put(180L, "邮政快递"); + ID_TO_NAME_LOGISTICS.put(181L, "郑州建华"); + ID_TO_NAME_LOGISTICS.put(182L, "中速快件"); + ID_TO_NAME_LOGISTICS.put(183L, "中天万运"); + ID_TO_NAME_LOGISTICS.put(184L, "中睿速递"); + ID_TO_NAME_LOGISTICS.put(185L, "增益速递"); + ID_TO_NAME_LOGISTICS.put(186L, "郑州速捷"); + ID_TO_NAME_LOGISTICS.put(187L, "智通物流"); + + // // 把enum中的最初的标准15个快递公司和其它也加进来 + // LogisticsCompanyEnum[] firstArray = LogisticsCompanyEnum.values(); + // for (int i = 0; i < firstArray.length; i++) { + // ID_TO_NAME_LOGISTICS.put(new Long(firstArray[i].getLogisticsCompanyId()), + // firstArray[i].getLogisticsCompanyName()); + // } + } } diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java new file mode 100644 index 0000000..57e988e --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java @@ -0,0 +1,21 @@ +package org.wcong.test.algorithm.cracking.dp_divide_conque; + +import java.util.List; + +/** + * given a boolean evaluation consisting of symbol + * 0(false),1(true),&(and),|(OR),and ^(XOR) and a desired boolean result Result + * implement a function to count the number of ways of parenthesizing the expressions + * such that it evaluates to result. + * the expression should be fully parenthesized + * + * @author wcong + * @since 19/04/2017 + */ +public class BooleanEvaluation { + + public int count(String expression, boolean result) { + return 0; + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/Basic.java b/src/main/java/org/wcong/test/concurrent/Basic.java new file mode 100644 index 0000000..29e0c0c --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/Basic.java @@ -0,0 +1,63 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class Basic { + + public static class MyThread extends Thread { + + private CountDownLatch countDownLatch; + + public MyThread(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running"); + } + } + + public static class MyRunner implements Runnable { + + private CountDownLatch countDownLatch; + + public MyRunner(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running too"); + } + } + + public static void main(String[] args) throws InterruptedException { + + CountDownLatch countDownLatch = new CountDownLatch(1); + Thread thread = new MyThread(countDownLatch); + thread.start(); + Thread secondThread = new Thread(new MyRunner(countDownLatch)); + secondThread.start(); + System.out.println("wait for it"); + thread.join(); + countDownLatch.countDown(); + TimeUnit.MILLISECONDS.sleep(1000); + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java b/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java new file mode 100644 index 0000000..dba2fa5 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java @@ -0,0 +1,27 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.CountDownLatch; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CountDownLatchThread implements Runnable { + + private CountDownLatch countDownLatch; + + public CountDownLatchThread(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + public void run() { + System.out.println("wait for it"); + countDownLatch.countDown(); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("start"); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java b/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java new file mode 100644 index 0000000..e3fec8a --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java @@ -0,0 +1,38 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CyclicBarrierPrint implements Runnable { + + private CyclicBarrier cyclicBarrier; + + public CyclicBarrierPrint(CyclicBarrier cyclicBarrier) { + this.cyclicBarrier = cyclicBarrier; + } + + @Override + public void run() { + System.out.println("I'm ready"); + try { + cyclicBarrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + System.out.println("I'm ready 1"); + try { + cyclicBarrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + System.out.println("we are finished"); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java b/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java new file mode 100644 index 0000000..f0cadd9 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java @@ -0,0 +1,30 @@ +package org.wcong.test.concurrent; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ExceptionHandler { + + public static class MyThread extends Thread { + public void run() { + throw new RuntimeException("hello exception"); + } + } + + public static class MyExceptionHandler implements Thread.UncaughtExceptionHandler { + + @Override + public void uncaughtException(Thread t, Throwable e) { + System.out.println(e.toString()); + } + } + + public static void main(String[] args) { + MyThread myThread = new MyThread(); + myThread.setUncaughtExceptionHandler(new MyExceptionHandler()); + myThread.start(); + System.out.println("haha"); + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/PhaserPrint.java b/src/main/java/org/wcong/test/concurrent/PhaserPrint.java new file mode 100644 index 0000000..4f22131 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/PhaserPrint.java @@ -0,0 +1,30 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.Phaser; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class PhaserPrint implements Runnable { + + private Phaser phaser; + + public PhaserPrint(Phaser phaser) { + this.phaser = phaser; + } + + @Override + public void run() { + System.out.println("thread:" + Thread.currentThread().getId() + ":print 1"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 2"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 3"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 4"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":finished"); + phaser.arriveAndDeregister(); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java b/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java new file mode 100644 index 0000000..8148f42 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java @@ -0,0 +1,46 @@ +package org.wcong.test.concurrent; + +import java.util.LinkedList; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ProducerAndComsumer { + + private static class Queue { + + private int maxSize; + + public Queue(int maxSize) { + this.maxSize = maxSize; + } + + LinkedList integerList = new LinkedList<>(); + + public synchronized Integer get() { + while (integerList.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return integerList.pop(); + + } + + public synchronized void add(Integer num) { + while (maxSize == integerList.size()) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + integerList.push(num); + } + + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java b/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java new file mode 100644 index 0000000..d50acc8 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java @@ -0,0 +1,25 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.Semaphore; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SemaphorePrint { + + private Semaphore semaphore = new Semaphore(2); + + public void print() { + try { + semaphore.acquire(); + System.out.println("acquire the semaphore :" + Thread.currentThread().getId() + ";"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + System.out.println("release the semaphore :" + Thread.currentThread().getId() + ";"); + semaphore.release(); + } + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java b/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java new file mode 100644 index 0000000..ce0d666 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java @@ -0,0 +1,60 @@ +package org.wcong.test.concurrent; + +import java.util.LinkedList; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SynchronizedMethod { + + LinkedList numList = new LinkedList<>(); + + public synchronized Integer get() { + System.out.println("Thread" + Thread.currentThread().getId() + "get the lock and sleep"); + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return numList.pop(); + } + + public synchronized void push(Integer num) { + System.out.println("Thread" + Thread.currentThread().getId() + "get the lock and sleep"); + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + numList.push(num); + } + + public static class MyGetThread extends Thread { + + private SynchronizedMethod synchronizedMethod; + + public MyGetThread(SynchronizedMethod synchronizedMethod) { + this.synchronizedMethod = synchronizedMethod; + } + + public void run() { + System.out.println("get " + synchronizedMethod.get()); + } + } + + public static class MyPutThread extends Thread { + + private SynchronizedMethod synchronizedMethod; + + public MyPutThread(SynchronizedMethod synchronizedMethod) { + this.synchronizedMethod = synchronizedMethod; + } + + public void run() { + synchronizedMethod.push(1); + System.out.println("put 1 "); + } + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/ThreadWait.java b/src/main/java/org/wcong/test/concurrent/ThreadWait.java new file mode 100644 index 0000000..0a834a4 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ThreadWait.java @@ -0,0 +1,33 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ThreadWait { + + public static class MyThread extends Thread { + public MyThread(String name) { + setName(name); + } + + public void run() { + TimeUnit.MILLISECONDS.toSeconds(1000); + System.out.println(getName()); + } + } + + public static void main(String[] args) throws InterruptedException { + MyThread thread1 = new MyThread("1"); + MyThread thread2 = new MyThread("2"); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + System.out.println("finished"); + + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java b/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java new file mode 100644 index 0000000..33a5852 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java @@ -0,0 +1,27 @@ +package org.wcong.test.concurrent; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class ThreadWithStop extends Thread { + + private boolean stop; + + public void setStop(boolean stop) { + this.stop = stop; + } + + public void run() { + while (!stop) { + try { + sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running"); + } + System.out.println("I stopped"); + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java b/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java new file mode 100644 index 0000000..20ad1ab --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CountDownLatchThreadTest { + + @Test + public void test() { + CountDownLatch countDownLatch = new CountDownLatch(10); + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new CountDownLatchThread(countDownLatch)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(100000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java b/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java new file mode 100644 index 0000000..9f6e9d1 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java @@ -0,0 +1,41 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CyclicBarrierPrintTest { + + public static class CyclicBarrierMonitor implements Runnable { + + private int stage; + + @Override + public void run() { + System.out.println("we all are ready for stage :" + stage++); + } + } + + @Test + public void test() { + CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new CyclicBarrierMonitor()); + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new CyclicBarrierPrint(cyclicBarrier)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java b/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java new file mode 100644 index 0000000..e716615 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class PhaserPrintTest { + + @Test + public void test() { + final Phaser phaser = new Phaser(10); // this will add to 10 emedialy,do not register again; + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new PhaserPrint(phaser)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java b/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java new file mode 100644 index 0000000..2dbd7b2 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java @@ -0,0 +1,44 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SemaphorePrintTest { + + static class PrintRunner implements Runnable { + + private SemaphorePrint semaphorePrint; + + public PrintRunner(SemaphorePrint semaphorePrint) { + this.semaphorePrint = semaphorePrint; + } + + @Override + public void run() { + semaphorePrint.print(); + } + } + + @Test + public void test() { + SemaphorePrint semaphorePrint = new SemaphorePrint(); + ExecutorService executor = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executor.submit(new PrintRunner(semaphorePrint)); + } + executor.shutdown(); + try { + executor.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java b/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java new file mode 100644 index 0000000..6e16b98 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java @@ -0,0 +1,26 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SynchronizedMethodTest { + + @Test + public void test() { + SynchronizedMethod synchronizedMethod = new SynchronizedMethod(); + SynchronizedMethod.MyPutThread myPutThread = new SynchronizedMethod.MyPutThread(synchronizedMethod); + myPutThread.start(); + SynchronizedMethod.MyGetThread myGetThread = new SynchronizedMethod.MyGetThread(synchronizedMethod); + myGetThread.start(); + try { + myGetThread.join(); + myPutThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java b/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java new file mode 100644 index 0000000..505e772 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class ThreadWithStopTest { + + @Test + public void testStop() { + ThreadWithStop thread = new ThreadWithStop(); + thread.start(); + try { + TimeUnit.MILLISECONDS.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("i will set you stop"); + thread.setStop(true); + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/package-info.java b/src/test/java/org/wcong/test/package-info.java new file mode 100644 index 0000000..45f186d --- /dev/null +++ b/src/test/java/org/wcong/test/package-info.java @@ -0,0 +1 @@ +package org.wcong.test; \ No newline at end of file From dd61f830be6ac8ea44b11152c848cd351c0e0b22 Mon Sep 17 00:00:00 2001 From: wcong Date: Sun, 7 May 2017 14:04:46 +0800 Subject: [PATCH 85/96] add some code --- src/main/java/org/wcong/App.java | 61 +++++++++--- .../leetcode/array/ReversePairs.java | 85 +++++++++++++++++ .../leetcode/string/TextJustifacation.java | 26 ++++++ .../tree/BinaryTreeMaximumSubPath.java | 41 +++++++++ .../leetcode/tree/InorderSuccessorInBST.java | 2 +- .../LowestCommonAncestorOfABinaryTree.java | 2 +- .../leetcode/tree/SumOfLeftLeaves.java | 2 +- .../algorithm/leetcode/tree/TreeNode.java | 6 +- .../leetcode/tree/ValidateBinaryTree.java | 34 +++---- .../wcong/test/hackerrank/package-info.java | 1 + .../hackerrank/string/BearAndSteadyGene.java | 92 +++++++++++++++++++ .../test/hackerrank/string/PerfectString.java | 64 +++++++++++++ .../wcong/test/hackerrank/package-info.java | 1 + .../string/BearAndSteadyGeneTest.java | 19 ++++ .../hackerrank/string/PerfectStringTest.java | 21 +++++ .../org/wcong/test/leetcode/package-info.java | 1 + .../leetcode/string/ReversePiarsTest.java | 25 +++++ .../tree/BinaryTreeMaximumSubPathTest.java | 28 ++++++ 18 files changed, 477 insertions(+), 34 deletions(-) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/ReversePairs.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java create mode 100644 src/main/java/org/wcong/test/hackerrank/package-info.java create mode 100644 src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java create mode 100644 src/main/java/org/wcong/test/hackerrank/string/PerfectString.java create mode 100644 src/test/java/org/wcong/test/hackerrank/package-info.java create mode 100644 src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java create mode 100644 src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/package-info.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index 4c3427a..a11a56c 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -1,9 +1,9 @@ package org.wcong; +import org.wcong.test.hackerrank.string.PerfectString; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Scanner; @@ -43,33 +43,72 @@ public static void buildSum(Node node, int depth) { } } } - static String stringGameWinner(String s, String p){ + + static String stringGameWinner(String s, String p) { // Complete this function boolean amandaWin; - if( s.length() 2*nums[j]. + * You need to return the number of important reverse pairs in the given array. + * + * @author wcong + * @since 04/05/2017 + */ +public class ReversePairs { + + public int reversePairsBruteForce(int[] nums) { + int pairs = 0; + for (int index = 0; index < nums.length; index++) { + for (int nextIndex = index + 1; nextIndex < nums.length; nextIndex++) { + if (nums[index] > 2 * nums[nextIndex]) { + pairs += 1; + } + } + } + return pairs; + } + + public int reversePairsDivideAndConquer(int[] nums) { + return reversePairsDivideAndConquer(nums, 0, nums.length - 1); + } + + private int reversePairsDivideAndConquer(int[] nums, int start, int end) { + if (start >= end) { + return 0; + } + int pairs = 0; + int middle = start + (end - start) / 2; + pairs += reversePairsDivideAndConquer(nums, start, middle); + pairs += reversePairsDivideAndConquer(nums, middle + 1, end); + int leftIndex = start; + for (int rightIndex = middle + 1; rightIndex <= end; rightIndex++) { + long currentNum = nums[rightIndex]; + for (; leftIndex <= middle; leftIndex++) { + if (2 * currentNum < nums[leftIndex]) { + pairs += middle - leftIndex + 1; + break; + } + } + } + + Arrays.sort(nums, start, end + 1); + return pairs; + } + + public int reversePairsLiner(int[] nums) { + List sorted = new LinkedList<>(); + int pairs = 0; + for (int soloNum : nums) { + pairs += countAndInsert(sorted, soloNum); + } + return pairs; + } + + private int countAndInsert(List sorted, Integer num) { + if (sorted.isEmpty()) { + sorted.add(num); + return 0; + } + int pairsIndex = 0; + int insertIndex = 0; + for (int integer : sorted) { + if (integer < num) { + insertIndex += 1; + } + if (integer > 2 * (long) num) { + break; + } + pairsIndex += 1; + } + sorted.add(insertIndex, num); + return sorted.size() - 1 - pairsIndex; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java new file mode 100644 index 0000000..2f9657f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java @@ -0,0 +1,26 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.List; + +/** + * Given an array of words and a length L, + * format the text such that each line has exactly L characters and is fully (left and right) justified. + *

+ * You should pack your words in a greedy approach; + * that is, pack as many words as you can in each line. + * Pad extra spaces ' ' when necessary so that each line has exactly L characters. + *

+ * Extra spaces between words should be distributed as evenly as possible. + * If the number of spaces on a line do not divide evenly between words, + * the empty slots on the left will be assigned more spaces than the slots on the right. + *

+ * For the last line of text, it should be left justified and no extra space is inserted between words. + * + * @author wcong + * @since 05/05/2017 + */ +public class TextJustifacation { + public List fullJustify(String[] words, int maxWidth) { + return null; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java new file mode 100644 index 0000000..21d5261 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * Given a binary tree, find the maximum path sum. + * For this problem, + * a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. + * The path must contain at least one node and does not need to go through the root. + * + * @author wcong + * @since 05/05/2017 + */ +public class BinaryTreeMaximumSubPath { + + private int maxPath; + + public int maxPathSum(TreeNode root) { + maxPath = Integer.MIN_VALUE; + maxSubPathSum(root); + return maxPath; + } + + private int maxSubPathSum(TreeNode node) { + if (node == null) { + return 0; + } + int left = maxSubPathSum(node.left); + int right = maxSubPathSum(node.right); + int maxSum = node.val; + if (left > 0) { + maxSum += left; + } + if (right > 0) { + maxSum += right; + } + if (maxPath < maxSum) { + maxPath = maxSum; + } + int max = left > right ? left : right; + return max > 0 ? max + node.val : node.val; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java index 50c477c..58534c8 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java @@ -17,7 +17,7 @@ public static TreeNode inOrderSuccessor(TreeNode root, TreeNode findNode) { TreeNode lastLeftNode = null; TreeNode compareNode = root; while (compareNode != null) { - if (findNode.value < compareNode.value) { + if (findNode.val < compareNode.val) { lastLeftNode = compareNode; compareNode = compareNode.left; } else { diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java index 8a047fe..5b27b0c 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java @@ -29,7 +29,7 @@ public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeN } private static boolean findNode(TreeNode treeNode, TreeNode findNode, List path) { - if (treeNode.value == findNode.value) { + if (treeNode.val == findNode.val) { return true; } else { if (treeNode.left != null) { diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java index aecf522..6bcffa2 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java @@ -25,7 +25,7 @@ public static int sumLeft(TreeNode root) { treeNodeStack.push(treeNode.right); } if (treeNode.left != null) { - sum += treeNode.left.value; + sum += treeNode.left.val; treeNodeStack.push(treeNode.left); } } diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java index ef339f1..bdb9ad8 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java @@ -5,10 +5,10 @@ */ public class TreeNode { - int value; + public int val; - TreeNode left; + public TreeNode left; - TreeNode right; + public TreeNode right; } diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java index 74913e8..576bdd1 100644 --- a/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java @@ -6,24 +6,24 @@ */ public class ValidateBinaryTree { - public static void main(String args) { - } + public static void main(String args) { + } - static int max = Integer.MIN_VALUE; + static int max = Integer.MIN_VALUE; - public static boolean validate(TreeNode treeNode) { - if (treeNode == null) { - return true; - } - if (!validate(treeNode.left)) { - return false; - } - if (treeNode.value >= max) { - max = treeNode.value; - } else { - return false; - } - return validate(treeNode.right); - } + public static boolean validate(TreeNode treeNode) { + if (treeNode == null) { + return true; + } + if (!validate(treeNode.left)) { + return false; + } + if (treeNode.val >= max) { + max = treeNode.val; + } else { + return false; + } + return validate(treeNode.right); + } } diff --git a/src/main/java/org/wcong/test/hackerrank/package-info.java b/src/main/java/org/wcong/test/hackerrank/package-info.java new file mode 100644 index 0000000..93dd5ef --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.hackerrank; \ No newline at end of file diff --git a/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java b/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java new file mode 100644 index 0000000..8a90365 --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java @@ -0,0 +1,92 @@ +package org.wcong.test.hackerrank.string; + +import java.util.HashMap; +import java.util.Map; + +/** + * given a string consist of A,C,T,G + * if each of it appear 1/4 time the length it's steady + * give a string of length n divisible of 4; + * replace a minimum substring for it make it steady + *

+ * one loop get all num if + * + * @author wcong + * @since 03/05/2017 + */ +public class BearAndSteadyGene { + + public int minimumReplace(String s) { + int expectNum = s.length() / 4; + char[] charArray = new char[] { 'A', 'C', 'T', 'G' }; + Map characterIntegerMap = new HashMap<>(); + for (char soloChar : charArray) { + characterIntegerMap.put(soloChar, 0); + } + for (int index = 0; index < s.length(); index++) { + characterIntegerMap.put(s.charAt(index), characterIntegerMap.get(s.charAt(index)) + 1); + } + for (char soloChar : charArray) { + int count = characterIntegerMap.get(soloChar); + if (count <= expectNum) { + characterIntegerMap.remove(soloChar); + } else { + characterIntegerMap.put(soloChar, count - expectNum); + } + } + if (characterIntegerMap.isEmpty()) { + return 0; + } + Map encounterMap = new HashMap<>(); + for (char soloChar : characterIntegerMap.keySet()) { + encounterMap.put(soloChar, 0); + } + + int start = 0; + int index = 0; + int minSub = Integer.MAX_VALUE; + while (!characterIntegerMap.containsKey(s.charAt(index))) { + index += 1; + start = index; + } + while (index < s.length()) { + if (characterIntegerMap.containsKey(s.charAt(index))) { + encounterMap.put(s.charAt(index), encounterMap.get(s.charAt(index)) + 1); + } + int compare = compare(characterIntegerMap, encounterMap); + if (compare == 0) { + int sub = index - start+1; + if (sub < minSub) { + minSub = sub; + } + } else if (compare > 0) { + while (start < index) { + while (!characterIntegerMap.containsKey(s.charAt(index))) { + start += 1; + } + encounterMap.put(s.charAt(index), encounterMap.get(s.charAt(index)) - 1); + if (compare(characterIntegerMap, encounterMap) < 0) { + break; + } + start+=1; + } + } + index += 1; + } + return minSub; + } + + private int compare(Map characterIntegerMap, Map encounterMap) { + boolean isEqual = true; + for (Map.Entry characterIntegerEntry : characterIntegerMap.entrySet()) { + int encounter = encounterMap.get(characterIntegerEntry.getKey()); + if (encounter > characterIntegerEntry.getValue()) { + return 1; + } else if (encounter < characterIntegerEntry.getValue()) { + isEqual = false; + } + } + return isEqual ? 0 : -1; + } + +} diff --git a/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java b/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java new file mode 100644 index 0000000..03e2275 --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java @@ -0,0 +1,64 @@ +package org.wcong.test.hackerrank.string; + +import java.util.ArrayList; +import java.util.List; + +/** + * give a string consisting of a,b,c,d + * perfect string + * 1 num of a equal num of b + * 2 num of c equal num of d + * subsequent of string + * + * @author wcong + * @since 03/05/2017 + */ +public class PerfectString { + + public long perfectNum(String originString) { + int[] count = new int[4]; + for (char soloChar : originString.toCharArray()) { + count[soloChar - 'a'] += 1; + } + long perfectNum = 0; + long abNum = 0; + int minAb = count[0] < count[1] ? count[0] : count[1]; + for (int i = 1; i <= minAb; i++) { + abNum += combination(count[0], i) * combination(count[1], i); + } + perfectNum += abNum % 1000000007; + int minCD = count[2] < count[3] ? count[2] : count[3]; + long cdNum = 0; + for (int i = 1; i <= minCD; i++) { + cdNum += combination(count[2], i) * combination(count[3], i); + } + perfectNum += cdNum % 1000000007; + perfectNum = perfectNum % 1000000007; + perfectNum += (abNum * cdNum) % 1000000007; + perfectNum = perfectNum % 1000000007; + return perfectNum; + } + + static List factorialList = new ArrayList<>(); + + static { + factorialList.add(0); + factorialList.add(1); + } + + private int combination(int total, int num) { + if (total == 0 || num == 0) { + return 0; + } + if (total == num) { + return 1; + } + if (factorialList.size() - 1 < total) { + for (int currentNum = factorialList.size(); currentNum <= total; currentNum++) { + factorialList.add(factorialList.get(currentNum - 1) * currentNum); + } + } + return factorialList.get(total) / factorialList.get(total - num) / factorialList.get(num); + } + +} diff --git a/src/test/java/org/wcong/test/hackerrank/package-info.java b/src/test/java/org/wcong/test/hackerrank/package-info.java new file mode 100644 index 0000000..93dd5ef --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.hackerrank; \ No newline at end of file diff --git a/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java b/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java new file mode 100644 index 0000000..8298e58 --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java @@ -0,0 +1,19 @@ +package org.wcong.test.hackerrank.string; + +import org.eclipse.core.runtime.Assert; +import org.junit.Test; + +/** + * @author wcong + * @since 04/05/2017 + */ +public class BearAndSteadyGeneTest { + + @Test + public void test() { + BearAndSteadyGene bearAndSteadyGene = new BearAndSteadyGene(); + Assert.isTrue(bearAndSteadyGene.minimumReplace("GAAATAAA") == 5); + + } + +} diff --git a/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java b/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java new file mode 100644 index 0000000..dab4d53 --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java @@ -0,0 +1,21 @@ +package org.wcong.test.hackerrank.string; + +import org.eclipse.core.runtime.Assert; +import org.junit.Test; + +/** + * @author wcong + * @since 03/05/2017 + */ +public class PerfectStringTest { + + @Test + public void test() { + PerfectString perfectString = new PerfectString(); + Assert.isTrue(perfectString.perfectNum("abcd") == 3); + Assert.isTrue(perfectString.perfectNum("abc") == 1); + Assert.isTrue(perfectString.perfectNum("ddc") == 2); + Assert.isTrue(perfectString.perfectNum("dddccc") == 19); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/package-info.java b/src/test/java/org/wcong/test/leetcode/package-info.java new file mode 100644 index 0000000..6c0fd94 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.leetcode; \ No newline at end of file diff --git a/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java b/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java new file mode 100644 index 0000000..1d2cf36 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java @@ -0,0 +1,25 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.ReversePairs; + +/** + * @author wcong + * @since 04/05/2017 + */ +public class ReversePiarsTest { + + @Test + public void test() { + int[] nums = new int[] { 1, 3, 4, 6, 8, 2 }; + int[] maxInt = new int[] { 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647 }; + ReversePairs reversePairs = new ReversePairs(); + Assert.assertTrue(reversePairs.reversePairsBruteForce(nums) == 2); + Assert.assertTrue(reversePairs.reversePairsDivideAndConquer(nums) == 2); + Assert.assertTrue(reversePairs.reversePairsDivideAndConquer(maxInt) == 0); + Assert.assertTrue(reversePairs.reversePairsLiner(new int[] { 1, 3, 4, 6, 8, 2 }) == 2); + Assert.assertTrue(reversePairs.reversePairsLiner(maxInt) == 0); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java b/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java new file mode 100644 index 0000000..ba5836a --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java @@ -0,0 +1,28 @@ +package org.wcong.test.leetcode.tree; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.tree.BinaryTreeMaximumSubPath; +import org.wcong.test.algorithm.leetcode.tree.TreeNode; + +/** + * @author wcong + * @since 05/05/2017 + */ +public class BinaryTreeMaximumSubPathTest { + + @Test + public void test() { + BinaryTreeMaximumSubPath maximumSubPath = new BinaryTreeMaximumSubPath(); + TreeNode treeNode = new TreeNode(); + treeNode.val = 1; + TreeNode left = new TreeNode(); + left.val = 2; + treeNode.left = left; + TreeNode right = new TreeNode(); + right.val = 3; + treeNode.right = right; + Assert.assertTrue(maximumSubPath.maxPathSum(treeNode) == 6); + } + +} From cdcf0a48b5b68719446fcc285c607fc2c4a016ca Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 9 May 2017 20:57:54 +0800 Subject: [PATCH 86/96] add NumbersOfIslands --- .../leetcode/array/NumbersOfIslands.java | 44 +++++++++++++++++++ .../leetcode/string/StrongPassword.java | 22 ++++++++++ .../leetcode/array/NUmbersOfIslandsTest.java | 24 ++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java new file mode 100644 index 0000000..7263b6f --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java @@ -0,0 +1,44 @@ +package org.wcong.test.algorithm.leetcode.array; + +/** + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. + * An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. + * You may assume all four edges of the grid are all surrounded by water. + * + * @author wcong + * @since 09/05/2017 + */ +public class NumbersOfIslands { + public int numIslandsBruteForce(char[][] grid) { + int nums = 0; + for (int row = 0; row < grid.length; row++) { + for (int column = 0; column < grid[row].length; column++) { + if (grid[row][column] == '1') { + nums += 1; + elimateLand(grid, row, column); + } + } + } + return nums; + } + + private void elimateLand(char[][] grid, int row, int column) { + if (grid[row][column] == '0') { + return; + } + grid[row][column] = '0'; + if (row > 0) { + elimateLand(grid, row - 1, column); + } + if (column > 0) { + elimateLand(grid, row, column - 1); + } + if (row < grid.length - 1) { + elimateLand(grid, row + 1, column); + } + if (column < grid[row].length - 1) { + elimateLand(grid, row, column + 1); + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java new file mode 100644 index 0000000..9788d58 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java @@ -0,0 +1,22 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * A password is considered strong if below conditions are all met: + * 1. It has at least 6 characters and at most 20 characters. + * 2. It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit. + * 3. It must NOT contain three repeating characters in a row ("...aaa..." is weak, but "...aa...a..." is strong, assuming other conditions are met). + * Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0. + * Insertion, deletion or replace of any one character are all considered as one change. + * + * @author wcong + * @since 07/05/2017 + */ +public class StrongPassword { + + public int strongPasswordDP(String s) { + int[][] distance = new int[s.length()][s.length()]; + + return distance[s.length()][s.length()]; + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java b/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java new file mode 100644 index 0000000..4a60777 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.NumbersOfIslands; + +/** + * @author wcong + * @since 09/05/2017 + */ +public class NUmbersOfIslandsTest { + + @Test + public void testNumIslandsBruteForce() { + NumbersOfIslands numbersOfIslands = new NumbersOfIslands(); + char[][] chars1 = new char[][] { "11110".toCharArray(), "11010".toCharArray(), "11000".toCharArray(), + "00000".toCharArray() }; + Assert.assertTrue(numbersOfIslands.numIslandsBruteForce(chars1) == 1); + char[][] chars2 = new char[][] { "11000".toCharArray(), "11000".toCharArray(), "00100".toCharArray(), + "00011".toCharArray() }; + Assert.assertTrue(numbersOfIslands.numIslandsBruteForce(chars2) == 3); + } + +} From 0de06756eddf038b9515528267ac807b7011b194 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 10 May 2017 19:50:58 +0800 Subject: [PATCH 87/96] add MaxPointsOnALine --- .../leetcode/array/MaxPointsOnALine.java | 162 ++++++++++++++++++ .../leetcode/array/MaxPointsOnALineTest.java | 33 ++++ 2 files changed, 195 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java new file mode 100644 index 0000000..2db32fd --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java @@ -0,0 +1,162 @@ +package org.wcong.test.algorithm.leetcode.array; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Given n points on a 2D plane + * find the maximum number of points that lie on the same straight line. + * + * @author wcong + * @since 10/05/2017 + */ +public class MaxPointsOnALine { + + public int maxPointsBruteForce(Point[] points) { + if (points == null) { + return 0; + } + if (points.length < 2) { + return points.length; + } + int maxPoints = 0; + for (int firstIndex = 0; firstIndex < points.length; firstIndex++) { + for (int secondIndex = firstIndex + 1; secondIndex < points.length; secondIndex++) { + Point firstPoint = points[firstIndex]; + Point secondPoint = points[secondIndex]; + double angel = 0; + if (firstPoint.y != secondPoint.y) { + angel = firstPoint.x > secondPoint.x ? + (firstPoint.x - secondPoint.x) / (firstPoint.y - secondPoint.y) : + (secondPoint.x - firstPoint.x) / (secondPoint.y - firstPoint.y); + } + int pointsNum = 2; + for (int leftIndex = secondIndex + 1; leftIndex < points.length; leftIndex++) { + Point nextPoint = points[leftIndex]; + if (firstPoint.y == nextPoint.y) { + if (firstPoint.y == secondPoint.y) { + pointsNum += 1; + } + continue; + } + double nextAngel = firstPoint.x > nextPoint.x ? + (firstPoint.x - nextPoint.x) / (firstPoint.y - nextPoint.y) : + (nextPoint.x - firstPoint.x) / (nextPoint.y - firstPoint.y); + if (angel == nextAngel) { + pointsNum += 1; + } + } + if (pointsNum > maxPoints) { + maxPoints = pointsNum; + } + } + } + return maxPoints; + } + + static class MyPoint { + Point point; + + String key; + + int count; + } + + public int maxPointsDp(Point[] points) { + if (points == null) { + return 0; + } + if (points.length < 2) { + return points.length; + } + Map pointCount = new HashMap<>(); + for (Point point : points) { + String key = point.x + "_" + point.y; + if (pointCount.containsKey(key)) { + pointCount.get(key).count += 1; + } else { + MyPoint myPoint = new MyPoint(); + myPoint.point = point; + myPoint.key = key; + myPoint.count = 1; + pointCount.put(key, myPoint); + } + } + List myPointList = new ArrayList<>(pointCount.values()); + if( myPointList.size()==1 ){ + return myPointList.get(0).count; + } + Set usedPoints = new HashSet<>(); + int maxPoints = 0; + for (int firstIndex = 0; firstIndex < myPointList.size(); firstIndex++) { + for (int secondIndex = firstIndex + 1; secondIndex < myPointList.size(); secondIndex++) { + MyPoint firstPoint = myPointList.get(firstIndex); + MyPoint secondPoint = myPointList.get(secondIndex); + if (usedPoints.contains(firstIndex + "_" + secondIndex)) { + continue; + } + double angel = 0; + if (firstPoint.point.y != secondPoint.point.y) { + angel = firstPoint.point.x > secondPoint.point.x ? + (firstPoint.point.x - secondPoint.point.x) / (double)(firstPoint.point.y - secondPoint.point.y) : + (secondPoint.point.x - firstPoint.point.x) / (double)(secondPoint.point.y - firstPoint.point.y); + } + int pointsNum = firstPoint.count + secondPoint.count; + List sameIndex = new LinkedList<>(); + for (int leftIndex = secondIndex + 1; leftIndex < myPointList.size(); leftIndex++) { + if (usedPoints.contains(secondIndex + "_" + leftIndex)) { + continue; + } + MyPoint nextPoint = myPointList.get(leftIndex); + if (firstPoint.point.y == nextPoint.point.y) { + if (firstPoint.point.y == secondPoint.point.y) { + for (Integer lastIndex : sameIndex) { + usedPoints.add(lastIndex + "_" + leftIndex); + } + sameIndex.add(leftIndex); + pointsNum += nextPoint.count; + } + continue; + } + double nextAngel = firstPoint.point.x > nextPoint.point.x ? + (firstPoint.point.x - nextPoint.point.x) / (double)(firstPoint.point.y - nextPoint.point.y) : + (nextPoint.point.x - firstPoint.point.x) / (double)(nextPoint.point.y - firstPoint.point.y); + if (angel == nextAngel) { + for (Integer lastIndex : sameIndex) { + usedPoints.add(lastIndex + "_" + leftIndex); + } + sameIndex.add(leftIndex); + pointsNum += nextPoint.count; + } + } + + if (pointsNum > maxPoints) { + maxPoints = pointsNum; + } + } + } + return maxPoints; + } + + public static class Point { + int x; + + int y; + + Point() { + x = 0; + y = 0; + } + + public Point(int a, int b) { + x = a; + y = b; + } + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java b/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java new file mode 100644 index 0000000..4d760e2 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java @@ -0,0 +1,33 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.MaxPointsOnALine; + +/** + * @author wcong + * @since 10/05/2017 + */ +public class MaxPointsOnALineTest { + + @Test + public void testMaxPoints() { + MaxPointsOnALine maxPointsOnALine = new MaxPointsOnALine(); + MaxPointsOnALine.Point[] points = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(0, 0), + new MaxPointsOnALine.Point(1, 1), new MaxPointsOnALine.Point(2, 2), new MaxPointsOnALine.Point(1, 0), + new MaxPointsOnALine.Point(2, 0) }; + MaxPointsOnALine.Point[] points1 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(0, 0), + new MaxPointsOnALine.Point(1, 1), new MaxPointsOnALine.Point(0, 0) }; + MaxPointsOnALine.Point[] points2 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(1, 1),new MaxPointsOnALine.Point(1, 1), + new MaxPointsOnALine.Point(2, 2) , new MaxPointsOnALine.Point(2, 2) }; + //[-4,1],[-7,7],[-1,5],[9,-25] + MaxPointsOnALine.Point[] points3 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(-4, 1),new MaxPointsOnALine.Point(-7, 7), + new MaxPointsOnALine.Point(-1, 5) , new MaxPointsOnALine.Point(9, -25) }; + Assert.assertTrue(maxPointsOnALine.maxPointsBruteForce(points) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points1) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points2) == 4); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points3) == 3); + } + +} From e06e44bb11481c38e97b004a45e75e7b8e7d099b Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 16 May 2017 20:39:41 +0800 Subject: [PATCH 88/96] add NumberToWords --- .../array/MedianOfTwoSortedArray.java | 52 ++++++++++++++ .../leetcode/numbers/NumberToWords.java | 68 +++++++++++++++++++ .../test/leetcode/NumberToWordsTest.java | 22 ++++++ .../array/MedianOfTwoSortedArrayTest.java | 20 ++++++ 4 files changed, 162 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java create mode 100644 src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java new file mode 100644 index 0000000..bdb6a74 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java @@ -0,0 +1,52 @@ +package org.wcong.test.algorithm.leetcode.array; + +/** + * There are two sorted arrays nums1 and nums2 of size m and n respectively. + * Find the median of the two sorted arrays. + * The overall run time complexity should be O(log (m+n)). + * ......*....... + * .....*...... + * + * @author wcong + * @since 11/05/2017 + */ +public class MedianOfTwoSortedArray { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + boolean isOdd = ((nums1.length + nums2.length) & 1) == 1; + int middle = (nums1.length + nums2.length) >> 1; + int nums1Start = 0; + int nums1End = nums1.length - 1; + int nums2Start = 0; + int nums2End = nums2.length - 1; + while (true) { + int nums1Middle = nums1Start + (nums1End - nums1Start) / 2; + int nums2Middle = nums2Start + (nums2End - nums2Start) / 2; + int currentPosition = nums1Middle + nums2Middle; + if (nums1[nums1Middle] == nums2[nums2Middle]) { + if (currentPosition == middle) { + break; + } else if (currentPosition < middle) { + nums1Start = nums1Middle; + nums2Start = nums2Middle; + } else { + nums1End = nums1Middle; + nums2End = nums2Middle; + } + } else if (nums1[nums1Middle] < nums2[nums2Middle]) { + nums2End = nums2Middle; + nums1Start = nums1Middle; + } else { + nums1End = nums1Middle; + nums2Start = nums2Middle; + } + if (nums1End == nums1Start && nums2End == nums2Start) { + break; + } + } + if (isOdd) { + return nums1[nums1End] > nums2[nums2End] ? nums1[nums1End] : nums2[nums2End]; + } else { + return ((double) (nums1[nums1End] + nums2[nums2End])) / 2; + } + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java b/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java new file mode 100644 index 0000000..3888218 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java @@ -0,0 +1,68 @@ +package org.wcong.test.algorithm.leetcode.numbers; + +/** + * Convert a non-negative integer to its english words representation. + * Given input is guaranteed to be less than 231 - 1. + * 123 -> "One Hundred Twenty Three" + * 12345 -> "Twelve Thousand Three Hundred Forty Five" + * 1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven" + * + * @author wcong + * @since 16/05/2017 + */ +public class NumberToWords { + + private static String[] LEVEL = new String[] { "", "Thousand", "Million", "Billion" }; + + private static String[] NUMBERS = new String[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", + "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", + "Eighteen", "Nineteen" }; + + private static String[] TEN_LEVEL = new String[] { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", + "Eighty", "Ninety" }; + + public String numberToWords(int num) { + if (num == 0) { + return "Zero"; + } + String words = ""; + int level = 0; + while (num > 0) { + String result = numberToWords(num % 1000, level); + if (words.length() > 0 && result.length() > 0) { + words = result + " " + words; + } else { + words = result + words; + } + num = num / 1000; + level += 1; + } + return words; + } + + private String numberToWords(int num, int level) { + StringBuilder stringBuilder = new StringBuilder(); + if (num >= 100) { + stringBuilder.append(NUMBERS[num / 100]).append(" ").append("Hundred"); + num = num % 100; + } + if (num >= 20) { + if (stringBuilder.length() > 0) { + stringBuilder.append(" "); + } + stringBuilder.append(TEN_LEVEL[num / 10]); + num = num % 10; + } + if (num > 0) { + if (stringBuilder.length() > 0) { + stringBuilder.append(" "); + } + stringBuilder.append(NUMBERS[num]); + } + if (level > 0 && stringBuilder.length() > 0) { + stringBuilder.append(" ").append(LEVEL[level]); + } + return stringBuilder.toString(); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java b/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java new file mode 100644 index 0000000..f8c0f8b --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java @@ -0,0 +1,22 @@ +package org.wcong.test.leetcode; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.numbers.NumberToWords; + +/** + * @author wcong + * @since 16/05/2017 + */ +public class NumberToWordsTest { + + @Test + public void testNumberToWords() { + NumberToWords numberToWords = new NumberToWords(); + Assert.assertTrue(numberToWords.numberToWords(123).equals("One Hundred Twenty Three")); + Assert.assertTrue(numberToWords.numberToWords(12345).equals("Twelve Thousand Three Hundred Forty Five")); + Assert.assertTrue(numberToWords.numberToWords(1234567) + .equals("One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven")); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java b/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java new file mode 100644 index 0000000..83a2cb5 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java @@ -0,0 +1,20 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.MedianOfTwoSortedArray; + +/** + * @author wcong + * @since 11/05/2017 + */ +public class MedianOfTwoSortedArrayTest { + + @Test + public void testFindMedianSortedArrays() { + MedianOfTwoSortedArray medianOfTwoSortedArray = new MedianOfTwoSortedArray(); + Assert.assertTrue(medianOfTwoSortedArray.findMedianSortedArrays(new int[] { 1, 3 }, new int[] { 2 }) == 2); + Assert.assertTrue(medianOfTwoSortedArray.findMedianSortedArrays(new int[] { 1, 3 }, new int[] { 3, 4 }) == 2.5); + } + +} From 18f86e03a19df1eff1c56a9234fab09645ef5de4 Mon Sep 17 00:00:00 2001 From: wcong Date: Wed, 7 Jun 2017 19:07:12 +0800 Subject: [PATCH 89/96] add ShortestPalindrome --- .../KthSmallestLexicographicalOrder.java | 67 ++++++++++++++ .../string/LongestValidParentheses.java | 82 +++++++++++++++++ .../leetcode/string/ShortestPalindrome.java | 41 +++++++++ .../SubstringWithConcatenationAllWords.java | 67 ++++++++++++++ .../algorithm/leetcode/string/WordBreak2.java | 89 +++++++++++++++++++ .../leetcode/string/WordSearch2.java | 56 ++++++++++++ .../KthSmallestLexicographicalOrderTest.java | 24 +++++ .../string/LongestValidParenthesesTest.java | 31 +++++++ .../string/ShortestPalindromeTest.java | 20 +++++ ...ubstringWithConcatenationAllWordsTest.java | 23 +++++ .../test/leetcode/string/WordBreak2Test.java | 31 +++++++ .../test/leetcode/string/WordSearch2Test.java | 27 ++++++ 12 files changed, 558 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java new file mode 100644 index 0000000..a8fa2da --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java @@ -0,0 +1,67 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.Arrays; + +/** + * Given integers n and k + * find the lexicographically k-th smallest integer in the range from 1 to n. + * Note: 1 ≤ k ≤ n ≤ 10^9. + * Example: + * Input: n: 13 k: 2 + * Output:10 + * Explanation: + * The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], + * so the second smallest number is 10. + * + * @author wcong + * @since 05/06/2017 + */ +public class KthSmallestLexicographicalOrder { + + public int findKthNumberBruteForce(int n, int k) { + String[] numbers = new String[n]; + for (int i = 1; i <= n; i++) { + numbers[i - 1] = String.valueOf(i); + } + Arrays.sort(numbers); + return Integer.parseInt(numbers[k - 1]); + } + + public static class Result { + boolean found = false; + int number = 1; + int order = 1; + } + + public int findKthNumberGreed(int n, int k) { + Result result = new Result(); + findKthNumberGreed(n, k, result); + return result.number; + } + + private void findKthNumberGreed(int n, int k, Result result) { + int number = result.number; + if (result.found) { + return; + } + for (int i = 0; i < 9; i++) { + if (result.order < k && number * 10 <= n) { + result.number = number * 10; + result.order += 1; + result.found = result.order == k; + findKthNumberGreed(n, k, result); + } + if (result.found) { + return; + } + number += 1; + if (number > n) { + return; + } + result.order += 1; + result.number = number; + result.found = result.order == k; + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java new file mode 100644 index 0000000..5dbe8be --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java @@ -0,0 +1,82 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.Stack; + +/** + * Given a string containing just the characters '(' and ')', + * find the length of the longest valid (well-formed) parentheses substring. + * For "(()", the longest valid parentheses substring is "()", which has length = 2. + * Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4. + * + * @author wcong + * @since 03/06/2017 + */ +public class LongestValidParentheses { + public int longestValidParenthesesBruteForce(String s) { + if (s == null || s.length() == 0) { + return 0; + } + int maxLength = 0; + for (int start = 0; start < s.length(); start++) { + for (int end = start + 1; end < s.length(); end++) { + if (isValidParentheses(s, start, end)) { + int length = end - start + 1; + if (length > maxLength) { + maxLength = length; + } + } + } + } + return maxLength; + } + + private boolean isValidParentheses(String s, int start, int end) { + Stack characterStack = new Stack<>(); + for (int i = start; i <= end; i++) { + if (s.charAt(i) == '(') { + characterStack.push('('); + } else if (s.charAt(i) == ')' && !characterStack.isEmpty() && characterStack.peek() == '(') { + characterStack.pop(); + } else { + return false; + } + } + return characterStack.isEmpty(); + } + + public int longestValidParenthesesGreed(String s) { + int maxLength = 0; + int leftNum = 0; + int rightNum = 0; + int startIndex = 0; + Stack characterStack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + characterStack.push(i); + leftNum += 1; + } else { + if (characterStack.isEmpty()) { + leftNum = 0; + rightNum = 0; + startIndex = i + 1; + } else { + characterStack.peek(); + rightNum += 1; + characterStack.pop(); + if (characterStack.isEmpty()) { + int length = i - startIndex + 1; + if (length > maxLength) { + maxLength = length; + } + leftNum = 0; + rightNum = 0; + } + } + } + } + if (leftNum >= rightNum && rightNum * 2 > maxLength) { + maxLength = rightNum * 2; + } + return maxLength; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java new file mode 100644 index 0000000..35c5738 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * Given a string S + * you are allowed to convert it to a palindrome by adding characters in front of it. + * Find and return the shortest palindrome you can find by performing this transformation. + * For example: + * Given "aacecaaa", return "aaacecaaa". + * Given "abcd", return "dcbabcd". + * + * @author wcong + * @since 07/06/2017 + */ +public class ShortestPalindrome { + + public String shortestPalindromeBruteForce(String s) { + StringBuilder insert = new StringBuilder(); + int end = s.length() - 1; + while (end > 0) { + if (isPalindrome(s, 0, end)) { + break; + } else { + insert.append(s.charAt(end)); + end -= 1; + } + } + return insert + s; + } + + private boolean isPalindrome(String s, int start, int end) { + while (start <= end) { + if (s.charAt(start) == s.charAt(end)) { + start += 1; + end -= 1; + } else { + return false; + } + } + return true; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java new file mode 100644 index 0000000..097cc02 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java @@ -0,0 +1,67 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * You are given a string, s, and a list of words, words, + * that are all of the same length. + * Find all starting indices of substring(s) in s + * that is a concatenation of each word in words + * exactly once and without any intervening characters. + * For example, given: + * s: "barfoothefoobarman" + * words: ["foo", "bar"] + * You should return the indices: [0,9]. + * (order does not matter). + * + * @author wcong + * @since 17/05/2017 + */ +public class SubstringWithConcatenationAllWords { + + public List findSubstringBruteForce(String s, String[] words) { + List indices = new LinkedList<>(); + if (words == null || words.length == 0) { + return indices; + } + int len = words[0].length(); + Map map = new HashMap<>(); + for (String word : words) { + if (map.containsKey(word)) { + map.put(word, map.get(word) + 1); + } else { + map.put(word, 1); + } + } + for (int index = 0; index < s.length(); index++) { + if (isConcatenation(s, index, new HashMap<>(map), len)) { + indices.add(index); + } + } + return indices; + } + + private boolean isConcatenation(String s, int index, Map map, int len) { + if (map.isEmpty()) { + return true; + } + if (index + len > s.length()) { + return false; + } + String nextWord = s.substring(index, index + len); + Integer num = map.get(nextWord); + if (num == null) { + return false; + } + if (num == 1) { + map.remove(nextWord); + } else { + map.put(nextWord, num - 1); + } + return isConcatenation(s, index + len, map, len); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java new file mode 100644 index 0000000..2ceb521 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java @@ -0,0 +1,89 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, + * add spaces in s to construct a sentence where each word is a valid dictionary word. + * You may assume the dictionary does not contain duplicate words. + * Return all such possible sentences. + * For example, given + * s = "catsanddog", + * dict = ["cat", "cats", "and", "sand", "dog"]. + * A solution is ["cats and dog", "cat sand dog"]. + * + * @author wcong + * @since 24/05/2017 + */ +public class WordBreak2 { + + public List wordBreakBruteForce(String s, List wordDict) { + Set wordSet = new HashSet<>(); + for (String word : wordDict) { + wordSet.add(word); + } + List wordBreakList = new LinkedList<>(); + breakWord(s, wordSet, 0, "", wordBreakList); + return wordBreakList; + } + + public List wordBreakDp(String s, List wordDict) { + Set wordSet = new HashSet<>(); + int maxLength = 0; + for (String word : wordDict) { + wordSet.add(word); + if (word.length() > maxLength) { + maxLength = word.length(); + } + } + List> breakWordList = new ArrayList<>(s.length()); + List firstChar = new LinkedList<>(); + breakWordList.add(firstChar); + + Map> map = new HashMap<>(); + if (wordSet.contains(s.substring(0, 1))) { + firstChar.add(s.substring(0, 1)); + } + map.put(s.substring(0, 1),firstChar); + for (int index = 1; index < s.length(); index++) { + List currentList = new ArrayList<>(); + for (int last = index; last >= 0 && (index - last) < maxLength; last--) { + String tempString = s.substring(last, index + 1); + if (wordSet.contains(tempString)) { + if (last == 0) { + currentList.add(tempString); + } else { + List lastBreakList = breakWordList.get(last - 1); + for (String lastBreak : lastBreakList) { + currentList.add(lastBreak + " " + tempString); + } + } + } + } + breakWordList.add(currentList); + } + return breakWordList.get(s.length() - 1); + } + + private void breakWord(String s, Set wordSet, int index, String currentWord, List wordBreakList) { + if (index >= s.length()) { + wordBreakList.add(currentWord); + return; + } + for (int nextIndex = index; nextIndex < s.length(); nextIndex++) { + String tempString = s.substring(index, nextIndex + 1); + if (wordSet.contains(tempString)) { + String temp = currentWord.length() == 0 ? tempString : currentWord + " " + tempString; + breakWord(s, wordSet, nextIndex + 1, temp, wordBreakList); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java new file mode 100644 index 0000000..d6dcac5 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java @@ -0,0 +1,56 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Given a 2D board and a list of words from the dictionary, + * find all words in the board. + * Each word must be constructed from letters of sequentially adjacent cell, + * where "adjacent" cells are those horizontally or vertically neighboring. + * The same letter cell may not be used more than once in a word. + * For example, + * Given words = ["oath","pea","eat","rain"] and board = + * [ + * ['o','a','a','n'], + * ['e','t','a','e'], + * ['i','h','k','r'], + * ['i','f','l','v'] + * ] + * Return ["eat","oath"]. + * + * @author wcong + * @since 26/05/2017 + */ +public class WordSearch2 { + + public List findWords(char[][] board, String[] words) { + Map> characterListMap = new HashMap<>(); + for (int rowIndex = 0; rowIndex < board.length; rowIndex++) { + char[] row = board[rowIndex]; + for (int columnIndex = 0; columnIndex < row.length; columnIndex++) { + char column = row[columnIndex]; + List indexList = characterListMap.get(column); + if (indexList == null) { + indexList = new LinkedList<>(); + characterListMap.put(column, indexList); + } + int[] index = new int[2]; + index[0] = rowIndex; + index[1] = columnIndex; + indexList.add(index); + } + } + List wordList = new LinkedList<>(); + for (String word : words) { + List firstIndexList = characterListMap.get(word.charAt(0)); + if (firstIndexList == null) { + continue; + } + boolean contains = false; + } + return wordList; + } +} diff --git a/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java b/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java new file mode 100644 index 0000000..55b26c3 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.KthSmallestLexicographicalOrder; + +/** + * @author wcong + * @since 06/06/2017 + */ +public class KthSmallestLexicographicalOrderTest { + + + @Test + public void testFindKthNumber() { + KthSmallestLexicographicalOrder solution = new KthSmallestLexicographicalOrder(); + Assert.assertTrue(solution.findKthNumberBruteForce(13, 2) == 10); + Assert.assertTrue(solution.findKthNumberGreed(13, 2) == 10); + Assert.assertTrue(solution.findKthNumberGreed(132, 4) == 101); + Assert.assertTrue(solution.findKthNumberGreed(10, 3) == 2); + Assert.assertTrue(solution.findKthNumberGreed(1000, 1000) == 9999); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java b/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java new file mode 100644 index 0000000..5aa3e6c --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.LongestValidParentheses; + +/** + * @author wcong + * @since 03/06/2017 + */ +public class LongestValidParenthesesTest { + + @Test + public void testLongestValidParentheses() { + String s1 = "(()"; + String s2 = ")()())"; + String s3 = ")()()))()()()(())"; + String s4 = "()(()"; + String s5 = "(()(((()"; + LongestValidParentheses solution = new LongestValidParentheses(); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s1) == 2); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s2) == 4); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s3) == 10); + Assert.assertTrue(solution.longestValidParenthesesGreed(s1) == 2); + Assert.assertTrue(solution.longestValidParenthesesGreed(s2) == 4); + Assert.assertTrue(solution.longestValidParenthesesGreed(s3) == 10); + Assert.assertTrue(solution.longestValidParenthesesGreed(s4) == 2); + Assert.assertTrue(solution.longestValidParenthesesGreed(s5) == 2); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java b/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java new file mode 100644 index 0000000..339a190 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java @@ -0,0 +1,20 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.ShortestPalindrome; + +/** + * @author wcong + * @since 07/06/2017 + */ +public class ShortestPalindromeTest { + + @Test + public void testShortestPalindrome() { + ShortestPalindrome solution = new ShortestPalindrome(); + Assert.assertTrue(solution.shortestPalindromeBruteForce("aacecaaa").equals("aaacecaaa")); + Assert.assertTrue(solution.shortestPalindromeBruteForce("abcd").equals("dcbabcd")); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java b/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java new file mode 100644 index 0000000..9919d80 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java @@ -0,0 +1,23 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.SubstringWithConcatenationAllWords; + +import java.util.Arrays; + +/** + * @author wcong + * @since 17/05/2017 + */ +public class SubstringWithConcatenationAllWordsTest { + + @Test + public void testFindSubstring() { + SubstringWithConcatenationAllWords test = new SubstringWithConcatenationAllWords(); + Assert.assertTrue(test.findSubstringBruteForce("barfoothefoobarman", new String[] { "foo", "bar" }) + .containsAll(Arrays.asList(0, 9))); + + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java b/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java new file mode 100644 index 0000000..90b0bbe --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java @@ -0,0 +1,31 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.WordBreak2; + +import java.util.Arrays; +import java.util.List; + +/** + * @author wcong + * @since 24/05/2017 + */ +public class WordBreak2Test { + + @Test + public void testWordBreak2() { + List dict = Arrays.asList("cat", "cats", "and", "sand", "dog"); + WordBreak2 wordBreak2 = new WordBreak2(); + List result = wordBreak2.wordBreakBruteForce("catsanddog", dict); + Assert.assertTrue(result.get(0).equals("cat sand dog")); + Assert.assertTrue(result.get(1).equals("cats and dog")); + List resultDp = wordBreak2.wordBreakDp("catsanddog", dict); + Assert.assertTrue(resultDp.get(1).equals("cat sand dog")); + Assert.assertTrue(resultDp.get(0).equals("cats and dog")); + List dictNone = Arrays.asList("aaaa", "aa"); + List resultDpNone = wordBreak2.wordBreakDp("aaaaaaa", dictNone); + Assert.assertTrue(resultDpNone.isEmpty()); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java b/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java new file mode 100644 index 0000000..7db6321 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java @@ -0,0 +1,27 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.WordSearch2; + +import java.util.List; + +/** + * @author wcong + * @since 26/05/2017 + */ +public class WordSearch2Test { + + @Test + public void testWordSearch2() { + char[][] board = new char[][]{{'o', 'a', 'a', 'n'}, + {'e', 't', 'a', 'e'}, + {'i', 'h', 'k', 'r'}, + {'i', 'f', 'l', 'v'}}; + WordSearch2 wordSearch2 = new WordSearch2(); + List result = wordSearch2.findWords(board, new String[]{"oath", "pea", "eat", "rain"}); + Assert.assertTrue(result.get(0).equals("oath")); + Assert.assertTrue(result.get(1).equals("eat")); + } + +} From 713857ddde4577f3acce280df2be198b7f76999b Mon Sep 17 00:00:00 2001 From: wcong Date: Mon, 19 Jun 2017 20:33:21 +0800 Subject: [PATCH 90/96] add Solution --- src/main/java/org/wcong/App.java | 1 + .../test/algorithm/leetcode/array/Candy.java | 47 +++++++ .../leetcode/array/CreateMaximumNumber.java | 126 ++++++++++++++++++ .../string/BestTimeBuySellStockIV.java | 78 +++++++++++ .../leetcode/string/InterleavingString.java | 52 ++++++++ .../string/PalindromePartitioning2.java | 48 +++++++ .../array/BestTimeBuySellStockIVTest.java | 28 ++++ .../wcong/test/leetcode/array/CandyTest.java | 23 ++++ .../array/CreateMaximumNumberTest.java | 38 ++++++ .../string/InterleavingStringTest.java | 24 ++++ .../string/PalindromePartitioning2Test.java | 21 +++ 11 files changed, 486 insertions(+) create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java create mode 100644 src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/CandyTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java create mode 100644 src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index a11a56c..da1598c 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -42,6 +42,7 @@ public static void buildSum(Node node, int depth) { } } } + } static String stringGameWinner(String s, String p) { diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java new file mode 100644 index 0000000..ee49783 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java @@ -0,0 +1,47 @@ +package org.wcong.test.algorithm.leetcode.array; + +/** + * There are N children standing in a line. Each child is assigned a rating value. + * You are giving candies to these children subjected to the following requirements: + * 1. Each child must have at least one candy. + * 2. Children with a higher rating get more candies than their neighbors. + * What is the minimum candies you must give? + * + * @author wcong + * @since 19/06/2017 + */ +public class Candy { + public int candy(int[] ratings) { + int candies = 1; + int[] candy = new int[ratings.length]; + candy[0] = 1; + for (int i = 1; i < ratings.length; i++) { + if (ratings[i] > ratings[i - 1]) { + candy[i] = candy[i - 1] + 1; + candies += candy[i]; + } else if (ratings[i] < ratings[i - 1]) { + int lastIndex = i; + int lastRating = ratings[i]; + while (lastIndex + 1 < ratings.length && lastRating > ratings[lastIndex + 1]) { + lastIndex += 1; + lastRating = ratings[lastIndex]; + } + int num = 1; + for (int j = lastIndex; j >= i; j--) { + candy[j] = num; + candies += num; + num += 1; + } + if (candy[i - 1] < num) { + candies += num - candy[i - 1]; + candy[i - 1] = num; + } + i = lastIndex; + } else { + candy[i] = 1; + candies += 1; + } + } + return candies; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java new file mode 100644 index 0000000..69d1768 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java @@ -0,0 +1,126 @@ +package org.wcong.test.algorithm.leetcode.array; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Given two arrays of length m and n with digits 0-9 representing two numbers. + * Create the maximum number of length k <= m + n from digits of the two. + * The relative order of the digits from the same array must be preserved. + * Return an array of the k digits. + * You should try to optimize your time and space complexity + * + * @author wcong + * @since 13/06/2017 + */ +public class CreateMaximumNumber { + + private int[] maxNumber; + + public int[] maxNumberBruteForce(int[] nums1, int[] nums2, int k) { + int total = nums1.length + nums2.length; + k = total > k ? k : total; + maxNumber = new int[k]; + iterateMaxNumber(nums1, 0, nums2, 0, new int[k], k); + return maxNumber; + } + + private void iterateMaxNumber(int[] nums1, int index1, int[] nums2, int index2, int[] number, int left) { + if (index1 >= nums1.length && index2 >= nums2.length && left > 0) { + return; + } + if (left <= 0) { + if (arrayCompare(number, maxNumber)) { + maxNumber = Arrays.copyOf(number, number.length); + } + return; + } + if (index1 < nums1.length) { + number[number.length - left] = nums1[index1]; + iterateMaxNumber(nums1, index1 + 1, nums2, index2, number, left - 1); + iterateMaxNumber(nums1, index1 + 1, nums2, index2, number, left); + } + if (index2 < nums2.length) { + number[number.length - left] = nums2[index2]; + iterateMaxNumber(nums1, index1, nums2, index2 + 1, number, left - 1); + iterateMaxNumber(nums1, index1, nums2, index2 + 1, number, left); + } + } + + private boolean arrayCompare(int[] array1, int[] array2) { + for (int i = 0; i < array2.length; i++) { + if (array1[i] > array2[i]) { + return true; + } else if (array1[i] < array2[i]) { + return false; + } + } + return false; + } + + static class Index { + public Index(boolean first, int index) { + this.first = first; + this.index = index; + } + + boolean first = false; + int index = 0; + } + + public int[] maxNumberGreed(int[] nums1, int[] nums2, int k) { + int total = nums1.length + nums2.length; + k = total > k ? k : total; + maxNumber = new int[k]; + maxNumberGreed(nums1, 0, nums2, 0, k, new int[k]); + return maxNumber; + } + + private void maxNumberGreed(int[] nums1, int index1, int[] nums2, int index2, int left, int[] current) { + if (left <= 0) { + if (arrayCompare(current, maxNumber)) { + maxNumber = Arrays.copyOf(current, current.length); + } + return; + } + List maxIndexList = findMaxIndex(nums1, index1, nums2, index2, left); + for (Index index : maxIndexList) { + if (index.first) { + current[current.length - left] = nums1[index.index]; + maxNumberGreed(nums1, index.index + 1, nums2, index2, left - 1, current); + } else { + current[current.length - left] = nums2[index.index]; + maxNumberGreed(nums1, index1, nums2, index.index + 1, left - 1, current); + } + } + } + + private List findMaxIndex(int[] nums1, int index1, int[] nums2, int index2, int left) { + List maxList = new ArrayList<>(); + int firstEnd = nums1.length - left + nums2.length - index2; + firstEnd = firstEnd >= nums1.length ? nums1.length - 1 : firstEnd; + int max = 0; + for (int i = index1; i <= firstEnd; i++) { + if (nums1[i] > max) { + maxList.clear(); + maxList.add(new Index(true, i)); + max = nums1[i]; + } else if (nums1[i] == max) { + maxList.add(new Index(true, i)); + } + } + int secondEnd = nums2.length - left + nums1.length - index1; + secondEnd = secondEnd >= nums2.length ? nums2.length - 1 : secondEnd; + for (int i = index2; i <= secondEnd; i++) { + if (nums2[i] > max) { + maxList.clear(); + maxList.add(new Index(false, i)); + max = nums2[i]; + } else if (nums2[i] == max) { + maxList.add(new Index(false, i)); + } + } + return maxList; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java new file mode 100644 index 0000000..c5b0250 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java @@ -0,0 +1,78 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * Say you have an array for which the ith element is the price of a given stock on day i. + * Design an algorithm to find the maximum profit. + * You may complete at most k transactions. + * Note: + * You may not engage in multiple transactions at the same time + * (ie, you must sell the stock before you buy again). + * + * @author wcong + * @since 08/06/2017 + */ +public class BestTimeBuySellStockIV { + + private Integer maxProfit; + + public int maxProfitBruteForce(int k, int[] prices) { + maxProfit = 0; + iterateOptions(k, 0, prices, false, 0, 0); + return maxProfit; + } + + private void iterateOptions(int transactions, int index, int[] prices, boolean isBuy, int currentPrice, int currentProfit) { + if (index >= prices.length || transactions <= 0) { + if (currentProfit > maxProfit) { + maxProfit = currentProfit; + } + return; + } + if (!isBuy) { + iterateOptions(transactions, index + 1, prices, true, prices[index], currentProfit); + iterateOptions(transactions, index + 1, prices, false, currentPrice, currentProfit); + } else { + iterateOptions(transactions - 1, index + 1, prices, false, prices[index], currentProfit + prices[index] - currentPrice); + iterateOptions(transactions, index + 1, prices, true, currentPrice, currentProfit); + } + } + + + static class Result { + int profit = 0; + int transactions = 0; + } + + public int maxProfitDp(int k, int[] prices) { + if (k <= 0 || prices.length == 0) { + return 0; + } + Result[] profits = new Result[prices.length]; + profits[0] = new Result(); + for (int i = 1; i < prices.length; i++) { + Result result = new Result(); + result.profit = prices[i] - prices[0]; + result.transactions = 1; + if (result.profit < 0) { + result.profit = 0; + result.transactions = 0; + } + for (int j = 1; j < i; j++) { + if (profits[j - 1].transactions + 1 > k) { + continue; + } + int profit = profits[j - 1].profit + prices[i] - prices[j]; + if (profit > result.profit) { + result.profit = profit; + result.transactions = profits[j - 1].transactions + 1; + } + } + if (profits[i - 1].profit > result.profit) { + result.profit = profits[i - 1].profit; + result.transactions = profits[i - 1].transactions; + } + profits[i] = result; + } + return profits[prices.length - 1].profit; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java new file mode 100644 index 0000000..6d03b21 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java @@ -0,0 +1,52 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * Given s1, s2, s3 + * find whether s3 is formed by the interleaving of s1 and s2. + * For example, + * Given: + * s1 = "aabcc", + * s2 = "dbbca", + * When s3 = "aadbbcbcac", return true. + * When s3 = "aadbbbaccc", return false. + * + * @author wcong + * @since 15/06/2017 + */ +public class InterleavingString { + public boolean isInterleaveBruteForce(String s1, String s2, String s3) { + if (s1.length() + s2.length() != s3.length()) { + return false; + } + return isInterleaveBruteForce(s1, 0, s2, 0, s3, 0); + } + + private boolean isInterleaveBruteForce(String s1, int index1, String s2, int index2, String s3, int index3) { + return (index3 < s3.length() + && index1 < s1.length() + && s3.charAt(index3) == s1.charAt(index1) && + isInterleaveBruteForce(s1, index1 + 1, s2, index2, s3, index3 + 1)) + || (index3 < s3.length() + && index2 < s2.length() + && s3.charAt(index3) == s2.charAt(index2) + && isInterleaveBruteForce(s1, index1, s2, index2 + 1, s3, index3 + 1)) + || (index3 == s3.length() && index1 + index2 == s3.length()); + } + + public boolean isInterleaveDp(String s1, String s2, String s3) { + if (s1.length() + s2.length() != s3.length()) { + return false; + } + boolean[][] matchMatrix = new boolean[s1.length() + 1][s2.length() + 1]; + matchMatrix[0][0] = true; + matchMatrix[1][0] = s3.charAt(0) == s1.charAt(0); + matchMatrix[0][1] = s3.charAt(0) == s2.charAt(0); + for (int i = 1; i < s3.length(); i++) { + int length = i + 1; + for (int index1 = 0; index1 < length && index1 < s1.length() && length - index1 < s2.length(); index1++) { + matchMatrix[index1][length - index1] = s3.charAt(i) == s1.charAt(index1) && matchMatrix[index1][length - index1 - 1]; + } + } + return matchMatrix[s1.length()][s2.length()]; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java new file mode 100644 index 0000000..ff9f155 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java @@ -0,0 +1,48 @@ +package org.wcong.test.algorithm.leetcode.string; + +/** + * Given a string s, + * partition s such that every substring of the partition is a palindrome. + * Return the minimum cuts needed for a palindrome partitioning of s. + * For example, given s = "aab", + * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + * + * @author wcong + * @since 07/06/2017 + */ +public class PalindromePartitioning2 { + + boolean[][] palindromeMatrix; + + public int minCutDp(String s) { + int[] minCut = new int[s.length()]; + palindromeMatrix = new boolean[s.length()][s.length()]; + minCut[0] = 0; + for (int i = 1; i < s.length(); i++) { + if (isPalindrome(s, 0, i)) { + minCut[i] = 0; + } else { + int minCutNum = minCut[i - 1] + 1; + for (int j = 1; j < i; j++) { + if (isPalindrome(s, j, i)) { + int cutNum = minCut[j - 1] + 1; + if (cutNum < minCutNum) { + minCutNum = cutNum; + } + } + } + minCut[i] = minCutNum; + } + } + return minCut[s.length() - 1]; + } + + private boolean isPalindrome(String s, int start, int end) { + if (s.charAt(start) == s.charAt(end) && (start + 1 >= end - 1 || palindromeMatrix[start + 1][end - 1])) { + palindromeMatrix[start][end] = true; + return true; + } else { + return false; + } + } +} diff --git a/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java b/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java new file mode 100644 index 0000000..c66f40f --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java @@ -0,0 +1,28 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.BestTimeBuySellStockIV; + +/** + * @author wcong + * @since 10/06/2017 + */ +public class BestTimeBuySellStockIVTest { + + @Test + public void testMaxProfit() { + BestTimeBuySellStockIV solution = new BestTimeBuySellStockIV(); + int[] simple = new int[]{0, 1}; + int[] oneMax = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}; + int[] transaction = new int[]{1, 2}; + int[] time = new int[]{48, 12, 60, 93, 97, 42, 25, 64, 17, 56, 85, 93, 9, 48, 52, 42, 58, 85, 81, 84, 69, 36, 1, 54, 23, 15, 72, 15, 11, 94}; + int[] border = new int[]{1, 4, 2}; + Assert.assertTrue(solution.maxProfitDp(2, simple) == 1); + Assert.assertTrue(solution.maxProfitDp(9, oneMax) == 8); + Assert.assertTrue(solution.maxProfitDp(1, transaction) == 1); + Assert.assertTrue(solution.maxProfitDp(2, border) == 3); + } + + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/CandyTest.java b/src/test/java/org/wcong/test/leetcode/array/CandyTest.java new file mode 100644 index 0000000..8d8b4a6 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/CandyTest.java @@ -0,0 +1,23 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.Candy; + +/** + * @author wcong + * @since 19/06/2017 + */ +public class CandyTest { + + @Test + public void testCandies() { + Candy candy = new Candy(); + Assert.assertTrue(candy.candy(new int[]{11111}) == 1); + Assert.assertTrue(candy.candy(new int[]{1, 2, 2}) == 4); + Assert.assertTrue(candy.candy(new int[]{5, 4, 3, 2, 1, 0}) == 21); + Assert.assertTrue(candy.candy(new int[]{5, 4, 4, 2, 1, 0}) == 13); + Assert.assertTrue(candy.candy(new int[]{4, 2, 3, 4, 1}) == 9); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java b/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java new file mode 100644 index 0000000..ff9720e --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java @@ -0,0 +1,38 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.CreateMaximumNumber; + +import java.util.Arrays; + +/** + * @author wcong + * @since 13/06/2017 + */ +public class CreateMaximumNumberTest { + + @Test + public void testMaxNumber() { + + CreateMaximumNumber solution = new CreateMaximumNumber(); + int[] e3nums1 = new int[]{3, 9}; + int[] e3nums2 = new int[]{8, 9}; + int[] e3result = new int[]{9, 8, 9}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e3nums1, e3nums2, 3), e3result)); + int[] e1nums1 = new int[]{3, 4, 6, 5}; + int[] e1nums2 = new int[]{9, 1, 2, 5, 8, 3}; + int[] e1result = new int[]{9, 8, 6, 5, 3}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e1nums1, e1nums2, 5), e1result)); + int[] e2nums1 = new int[]{6, 7}; + int[] e2nums2 = new int[]{6, 0, 4}; + int[] e2result = new int[]{6, 7, 6, 0, 4}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e2nums1, e2nums2, 5), e2result)); + try { + throw new NoClassDefFoundError(); + } catch (Error e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java b/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java new file mode 100644 index 0000000..245ba95 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.InterleavingString; + +/** + * @author wcong + * @since 15/06/2017 + */ +public class InterleavingStringTest { + + @Test + public void testIsInterleave() { + String s1 = "aabcc"; + String s2 = "dbbca"; + String s3 = "aadbbcbcac"; + String s4 = "aadbbbaccc"; + InterleavingString solution = new InterleavingString(); + Assert.assertTrue(solution.isInterleaveBruteForce(s1, s2, s3)); + Assert.assertTrue(!solution.isInterleaveBruteForce(s1, s2, s4)); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java b/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java new file mode 100644 index 0000000..e24a894 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java @@ -0,0 +1,21 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.PalindromePartitioning2; + +/** + * @author wcong + * @since 07/06/2017 + */ +public class PalindromePartitioning2Test { + + @Test + public void testMinCutBruteForceDp() { + PalindromePartitioning2 solution = new PalindromePartitioning2(); + Assert.assertTrue(solution.minCutDp("aab") == 1); + Assert.assertTrue(solution.minCutDp("daa") == 1); + Assert.assertTrue(solution.minCutDp("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") == 1); + } + +} From d7d169917b5cff76564f78a1a6691737826ffb82 Mon Sep 17 00:00:00 2001 From: cong Date: Thu, 27 Jul 2017 15:24:20 +0800 Subject: [PATCH 91/96] Update README.md add algorithm link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8d6bb47..8e7f72c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ## learn-java example of learn java +algorithm has moved to [learn-algorithm](https://github.com/wcong/learn-algorithm) From e8be31ec838d5ecf0adbbe421c73571eb0287a3a Mon Sep 17 00:00:00 2001 From: cong Date: Thu, 27 Jul 2017 15:25:00 +0800 Subject: [PATCH 92/96] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8e7f72c..916e80b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ## learn-java example of learn java + algorithm has moved to [learn-algorithm](https://github.com/wcong/learn-algorithm) From e33b88e113f3fc5755e3aa16d425fee16055dad9 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 30 Jan 2018 20:46:22 +0800 Subject: [PATCH 93/96] MyPublisher --- pom.xml | 5 + .../org/wcong/test/rxjava/MyPublisher.java | 116 ++++++++++++++++++ .../org/wcong/test/rxjava/package-info.java | 3 + 3 files changed, 124 insertions(+) create mode 100644 src/main/java/org/wcong/test/rxjava/MyPublisher.java create mode 100644 src/main/java/org/wcong/test/rxjava/package-info.java diff --git a/pom.xml b/pom.xml index b4466ad..2cf092f 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,11 @@ jackson-annotations 2.3.3 + + io.reactivex.rxjava2 + rxjava + 2.1.6 + org.freemarker freemarker diff --git a/src/main/java/org/wcong/test/rxjava/MyPublisher.java b/src/main/java/org/wcong/test/rxjava/MyPublisher.java new file mode 100644 index 0000000..c2b58b0 --- /dev/null +++ b/src/main/java/org/wcong/test/rxjava/MyPublisher.java @@ -0,0 +1,116 @@ +package org.wcong.test.rxjava; + +import io.reactivex.Flowable; +import io.reactivex.FlowableSubscriber; +import io.reactivex.Scheduler; +import io.reactivex.schedulers.Schedulers; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +public class MyPublisher { + + private static CountDownLatch countDownLatch = new CountDownLatch(4); + + public static void main(String[] args) throws InterruptedException { + new ParallelFlowableRange(1, 100, Schedulers.computation()).subscribe(i -> { + System.out.println(Thread.currentThread().getName() + ":" + i); + }, e -> System.out.println(Thread.currentThread().getName() + ":" + e), () -> System.out.println(Thread.currentThread().getName() + ":complete")); + countDownLatch.await(); + } + + + public static class ParallelFlowableRange extends Flowable { + + private Scheduler scheduler; + + private int start; + private int end; + + public ParallelFlowableRange(int start, int end, Scheduler scheduler) { + this.scheduler = scheduler; + this.start = start; + this.end = end; + } + + @Override + protected void subscribeActual(Subscriber subscriber) { + AtomicInteger atomicInteger = new AtomicInteger(start); + for (int i = 0; i < 4; i++) { + MySubscriber mySubscriber = new MySubscriber(subscriber, Integer.MAX_VALUE, scheduler.createWorker(), atomicInteger, end); + mySubscriber.onSubscribe(mySubscriber); + } + } + } + + public static class MySubscriber extends AtomicInteger implements FlowableSubscriber, Subscription, Runnable { + + private int prefetch; + private Scheduler.Worker worker; + private Subscriber actual; + private boolean cancel; + private AtomicInteger atomicInteger; + private int end; + + public MySubscriber(Subscriber actual, int prefetch, Scheduler.Worker worker, AtomicInteger atomicInteger, int end) { + this.actual = actual; + this.prefetch = prefetch; + this.worker = worker; + this.atomicInteger = atomicInteger; + this.end = end; + } + + @Override + public void onSubscribe(Subscription subscription) { + subscription.request(prefetch); + } + + @Override + public void onNext(Integer integer) { + actual.onNext(integer); + } + + @Override + public void onError(Throwable throwable) { + actual.onError(throwable); + } + + @Override + public void onComplete() { + countDownLatch.countDown(); + actual.onComplete(); + } + + @Override + public void request(long l) { + worker.schedule(this); + } + + @Override + public void cancel() { + cancel = true; + } + + @Override + public void run() { + while (true) { + if (cancel) { + break; + } + int num = atomicInteger.getAndIncrement(); + if (num < end) { + try { + onNext(num); + } catch (Exception e) { + onError(e); + } + } else { + onComplete(); + break; + } + } + } + } +} diff --git a/src/main/java/org/wcong/test/rxjava/package-info.java b/src/main/java/org/wcong/test/rxjava/package-info.java new file mode 100644 index 0000000..7b13049 --- /dev/null +++ b/src/main/java/org/wcong/test/rxjava/package-info.java @@ -0,0 +1,3 @@ +package org.wcong.test.rxjava; + +// about rxjava \ No newline at end of file From 640cf30ecaf59c761d34232d605cea66842fddc2 Mon Sep 17 00:00:00 2001 From: wcong Date: Tue, 30 Jan 2018 21:03:23 +0800 Subject: [PATCH 94/96] 1.7 --- src/main/java/org/wcong/test/rxjava/MyPublisher.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/wcong/test/rxjava/MyPublisher.java b/src/main/java/org/wcong/test/rxjava/MyPublisher.java index c2b58b0..307c6cd 100644 --- a/src/main/java/org/wcong/test/rxjava/MyPublisher.java +++ b/src/main/java/org/wcong/test/rxjava/MyPublisher.java @@ -3,6 +3,7 @@ import io.reactivex.Flowable; import io.reactivex.FlowableSubscriber; import io.reactivex.Scheduler; +import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -15,9 +16,12 @@ public class MyPublisher { private static CountDownLatch countDownLatch = new CountDownLatch(4); public static void main(String[] args) throws InterruptedException { - new ParallelFlowableRange(1, 100, Schedulers.computation()).subscribe(i -> { - System.out.println(Thread.currentThread().getName() + ":" + i); - }, e -> System.out.println(Thread.currentThread().getName() + ":" + e), () -> System.out.println(Thread.currentThread().getName() + ":complete")); + new ParallelFlowableRange(1, 100, Schedulers.computation()).subscribe(new Consumer() { + @Override + public void accept(Integer integer) throws Exception { + System.out.println(Thread.currentThread().getName() + ":" + integer); + } + }); countDownLatch.await(); } From 2361876d5edf1ec9670ecb9706446ed735291920 Mon Sep 17 00:00:00 2001 From: conwan Date: Fri, 7 Jun 2019 17:52:27 +0800 Subject: [PATCH 95/96] #1 rename file --- ...ongestCommonSubsequence.java => LongestCommonSubSequence.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/org/wcong/test/algorithm/dp/{LongestCommonSubsequence.java => LongestCommonSubSequence.java} (100%) diff --git a/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java b/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubSequence.java similarity index 100% rename from src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubsequence.java rename to src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubSequence.java From 9a7899ec8407f6545a71a426fd43ec046590d2e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 01:11:55 +0000 Subject: [PATCH 96/96] Bump junit from 4.12 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc06de3..5f4edf1 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ junit junit - 4.12 + 4.13.1 test