zoukankan      html  css  js  c++  java
  • 后台开发 3个题目 array_chunk, 100块钱找零钱(动态规划 dynamic programming), 双向循环链表 llist 删除节点

    1. array_chunk 实现

       http://php.net/manual/en/function.array-chunk.php

    <?php
    function my_array_chunk($a, $sz) {
    	$b = [];
    	if ($sz < 1) {
            throw new Exception("size is less than 1");
    		return null;
    	}
    	for ($i = 0, $n = count($a); $i < $n; $i++) {
    		if ($i % $sz === 0) {
    			array_push($b, []);
    		}
    		array_push($b[count($b) - 1], $a[$i]);
    	}
    	return $b;
    }
    

      

      test:

    $input_array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
    print_r(my_array_chunk($input_array, 3));
    // print_r(my_array_chunk($input_array, 2));
    test my_array_chunk()

      output: 

    E:codephp>php chunk.php
    Array
    (
        [0] => Array
            (
                [0] => a
                [1] => b
                [2] => c
            )
    
        [1] => Array
            (
                [0] => d
                [1] => e
                [2] => f
            )
    
        [2] => Array
            (
                [0] => g
                [1] => h
            )
    
    )
    php chunk.php

      javascript:

    Array.prototype.chunk = function(sz) {
        var a = [];
        if (sz<1) {
           	throw new Error("size is less than 1");
        }
        this.forEach(function(e, i) {
            if (i % sz === 0) {
                a.push([]);
            }
            a[a.length-1].push(e);         
        });
        return a;
    };
    

      

      test:

    var a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    console.log(a.chunk(2));
    console.log(a.chunk(1));
    console.log(a.chunk(8));
    console.log(a.chunk(10));
    console.log(a.chunk(0));
    test Array.prototype.chunk

      output:

    E:codejsalgorithm>node array_chunk.js
    [ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e', 'f' ], [ 'g', 'h' ] ]
    [ [ 'a' ],
      [ 'b' ],
      [ 'c' ],
      [ 'd' ],
      [ 'e' ],
      [ 'f' ],
      [ 'g' ],
      [ 'h' ] ]
    [ [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ] ]
    [ [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ] ]
    [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ]
    output for Array.prototype.chunk

    * golang

    // HelloWorld project main.go

    package main
    
    import (
    	"fmt"
    )
    
    func array_chunk(a []string, sz int) [][]string {
    	var n int = len(a)/sz   // 二维数组的长度
        if (len(a)>n*sz) { n += 1 }
    	var b = make([][]string, 0, n)
    
    	for i := 0; i < len(a); i++ {
    		offset := i % sz
    		if offset == 0 {
    			b = append(b, make([]string, sz))
    		}
    		b[len(b)-1][offset] = a[i]
    	}
    	return b
    }
    
    func slice2d_toString(a [][]string) string {
    	s := "["
    
    	for i := 0; i < len(a); i++ {
    		s += "["
    		j := 0
    		for ; j < len(a[i])-1; j++ {
    			s += a[i][j] + ","
    		}
    		s += a[i][j] + "] "
    	}
    
    	s += "]"
    	return s
    }
    
    func main() {
    	letters := []string{"a", "b", "c", "d", "e", "f", "g"}
    	a2d := array_chunk(letters, 3)
    	fmt.Printf(slice2d_toString(a2d))
    }
    

      output:

    C:/go/bin/go.exe build -i [J:/gocode/src/HelloWorld]
    成功: 进程退出代码 0.
    J:/gocode/src/HelloWorld/HelloWorld.exe  [J:/gocode/src/HelloWorld]
    [[a,b,c] [d,e,f] [g,,] ]成功: 进程退出代码 0.
    go output

    Java:

    package cn.mediamix;
    
    import java.util.ArrayList;
    
    public class ArrayChunk {
    	
    	private static ArrayList<ArrayList<String>> arrayChunk(String[] input, int sz) 
    			throws Exception {
    		ArrayList<ArrayList<String>> a = new ArrayList<ArrayList<String>>();
    		if (sz < 1) {
    			throw new Exception("size is less than 1");
    		}
    		for (int i = 0, n = input.length; i < n; i++) {
    			if (i % sz == 0) {
    				a.add(new ArrayList<String>());
    			}
    			a.get(a.size()-1).add(input[i]);
    		}
    		
    		return a;
    	}
    
    	public static void main(String[] args) {
    		String[] input = {"a", "b", "c", "d", "e", "f", "g", "h"};
    		ArrayList<ArrayList<String>> a = null;
    		try {
    			a = arrayChunk(input, 3);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		System.out.println(a.toString());
    	}
    }
    

      Output: 

    [[a, b, c], [d, e, f], [g, h]]

    2. 100块钱 找零钱多少种方法  50, 20, 10, 5, 1

       查一下贪心算法、0/1背包问题  (343种, 但是套4层循环不是好的方法)

      先看一个简单一点的问题: 93块钱找零钱,用最少的note/coins数怎么做?

    function findMin(deno, v) {
        deno = deno.sort(function(a, b) {
           return b-a;
        });
        var ans = [];
        deno.forEach(function(item) {
            while (v >= item) {
                v -= item;
                ans.push(item);
            }
        });
        return ans;
    }
    
    var deno = [50, 20, 10, 5, 1];
    console.log(findMin(deno, 93));
    

      output: 

    [ 50, 20, 20, 1, 1, 1 ]

    100块钱, 用面值 [ 50, 20, 10, 5, 1 ]的钱币, 换零钱多少种方法?

    用动态规划法:

    php:

    <?php
    function coins($deno, $v) {
        $n = count($deno);
        $dp = [];
        for ($i = 0; $i < $n; $i++) {
            $dp[$i] = [];  // length: $v+1
            $dp[$i][0] = 1; //第一列为1
        }
        for ($j = 0; $j <= $v; $j++) {
            // 第一行中能够被$deno[0]整除的数,即可以被换钱,记为1
            $dp[0][$j] = $j % $deno[0]===0 ? 1 : 0;
        }
        for ($i = 1; $i < $n; $i++) {
            for ($j = 1; $j <= $v; $j++) {
                $tmp = 0;
                for ($k = 0; $k * $deno[$i] <= $j; $k++) {
                    // 累加用$k张$deno[i]货币后$dp[i-1]中组成剩下钱数的方法数
                    $tmp += $dp[$i-1][ $j - $k * $deno[$i] ];
                }
                $dp[$i][$j] = $tmp;
            }
        }
        return $dp[$n-1][$v];
    }
    
    // test
    $deno = [50,20,10,5,1];
    echo coins($deno, 100).PHP_EOL;
    

      

    javascript:

    function coins(deno, v) {
        if (deno === null || deno.length === 0 || v < 0) {
            return 0;
        }
        var dp = new Array(v + 1);
        // init
        for (var i = 0; i < dp.length; i++) {
            dp[i] = 0;
        }
        for (var j = 0; deno[0] * j <= v; j++) {
            dp[deno[0] * j] = 1;
        }
        for (i = 1; i < deno.length; i++) {
            for (j = 1; j <= v; j++) {
                dp[j] += j - deno[i] >= 0 ? dp[j - deno[i]] : 0;
            }
        }
        return dp[v];
    }
    

      

    // test
    var deno = [50, 20, 10, 5, 1];
    console.log(coins(deno, 100));  // 343

    golang: 

    // Dynamic programming project main.go
    package main
    
    import (
    	"fmt"
    )
    
    func coin(deno []int, v int) int {
    	n := len(deno)
    	dp := make([][]int, 0, n)
    	for i := 0; i < n; i++ {
    		dp = append(dp, make([]int, v+1))
    		dp[i][0] = 1
    	}
    	for j := 0; j <= v; j++ {
    		if j%deno[0] == 0 {
    			dp[0][j] = 1
    		} else {
    			dp[0][j] = 0
    		}
    	}
    	for i := 1; i < n; i++ {
    		for j := 1; j <= v; j++ {
    			tmp := 0
    			for k := 0; k*deno[i] <= j; k++ {
    				tmp += dp[i-1][j-k*deno[i]]
    			}
    			dp[i][j] = tmp
    		}
    	}
    	return dp[n-1][v]
    }
    
    func main() {
    	deno := make([]int, 0, 5)
    	deno = append(deno, 50, 20, 10, 5, 1)
    
    	/*
    		for i := range deno {
    			fmt.Println(deno[i])
    		}
    	*/
    	c := coin(deno, 100)
    	fmt.Println(c)
    }
    

      output:

    /usr/local/go/bin/go build -i [/Users/Mch/Code/golang/src/Greedy]
    Success: process exited with code 0.
    /Users/Mch/Code/golang/src/Greedy/Greedy  [/Users/Mch/Code/golang/src/Greedy]
    343
    Success: process exited with code 0.
    main.go output

    Java:

    package cn.mediamix;
    
    public class Coins {
    	
    	public static int coins(int []deno, int v) {
    		if (deno == null || deno.length == 0 || v < 0) {
    			return 0;
    		}
    		int[] dp = new int[v+1];
    		for (int j = 0; deno[0] * j <= v; j++) {
    			dp[deno[0]*j] = 1;
    		}
    		for (int i = 1; i < deno.length; i++) {
    			for (int j = 1; j <= v; j++) {
    				dp[j] += j - deno[i] >= 0 ? dp[j-deno[i]] : 0;
    			}
    		}
    		return dp[v];
    	}
    
    	public static void main(String[] args) {
    		int []deno = {50, 20, 10, 5, 1};
    		int solutions = Coins.coins(deno, 100);
    		System.out.println(solutions);
    	}
    
    }

      output:  343 

    3. 双向链表删除节点 (只有1个节点怎么处理)

       为了让链表的元素适应任何类型, 参照内核链表. http://kernel.org

        ~/linux-4.17.11/include/linux/list.h

        ~/linux-4.17.11/include/linux/kernel.h

        ~/linux-4.17.11/include/linux/stddef.h

        ~/linux-4.17.11/include/linux/poison.h

      llist.h

    #ifndef llist_h
    #define llist_h
    
    struct list_head {
        struct list_head *next;
        struct list_head *prev;
    };
    
    // #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
    
    #define list_entry(ptr, type, member)  
    container_of(ptr, type, member)
    
    #define container_of(ptr, type, member) ({ 
    void *__mptr = (void *)(ptr);   
    ((type *)(__mptr - offsetof(type, member))); })
    
    #define LIST_HEAD_INIT(name) { &(name), &(name) }
    
    #define LIST_HEAD(name) 
    struct list_head name = LIST_HEAD_INIT(name)
    
    static inline void INIT_LIST_HEAD(struct list_head *list)
    {
        list->next = list;
        list->prev = list;
    }
    
    static inline void __list_add(struct list_head *new,
                                  struct list_head *prev,
                                  struct list_head *next)
    {
        next->prev = new;
        new->next = next;
        new->prev = prev;
        prev->next = new;
    }
    
    static inline void list_add_tail(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head->prev, head);
    }
    
    static inline void list_add(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head, head->next);
    }
    
    static inline void __list_del(struct list_head * prev, struct list_head * next)
    {
        next->prev = prev;
        prev->next = next;
    }
    
    static inline void __list_del_entry(struct list_head *entry)
    {
        // if (!__list_del_entry_valid(entry)) return;
        __list_del(entry->prev, entry->next);
    }
    
    #define POISON_POINTER_DELTA 0
    
    #define LIST_POISON1  ((void *) 0x100 + POISON_POINTER_DELTA)
    #define LIST_POISON2  ((void *) 0x200 + POISON_POINTER_DELTA)
    
    static inline void list_del(struct list_head *entry)
    {
        __list_del_entry(entry);
        entry->next = LIST_POISON1;
        entry->prev = LIST_POISON2;
    }
    

      

    main.c

    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include "llist.h"
    
    struct fox {
        unsigned long tail_length;
        unsigned long weight;
        bool is_fantastic;
        struct list_head list;
    };
    
    void handler(struct fox *f) {
        printf("tail length: %lu, weight=%lu, fantasic: %d
    ",
               f->tail_length, f->weight, f->is_fantastic?1:0);
    }
    
    struct fox *list_traverse(const struct list_head *fox_list,
                              void (*handler)(struct fox *f)) {
        // 链表指针(不包含元素)迭代器
        struct list_head *p;
        // 链表整个节点迭代器
        struct fox *f = NULL;
        
        list_for_each(p, fox_list) {
            f = list_entry(p, struct fox, list);
            handler(f);
        }
        return f;
    }
    
    int main(int argc, const char * argv[]) {
        /*
        struct fox *red_fox = (struct fox *)malloc(sizeof(*red_fox));    
        red_fox->tail_length = 40;
        red_fox->weight = 6;
        red_fox->is_fantastic = false;
        INIT_LIST_HEAD(&red_fox->list);
        */
        struct fox red_fox = {
            .tail_length = 40,
            .weight = 6,
            .is_fantastic = false,
            .list = LIST_HEAD_INIT(red_fox.list)
        };
        
        struct fox new_fox = {
            .tail_length = 35,
            .weight = 5,
            .is_fantastic = true,
            .list = LIST_HEAD_INIT(new_fox.list)
        };
        // 初始化表头
        LIST_HEAD(fox_list);
        // 添加2个节点
        list_add_tail(&red_fox.list, &fox_list);
        list_add_tail(&new_fox.list, &fox_list);
        
        struct fox *f = list_traverse(&fox_list, handler);
        
        // 删除最后添加的一个节点
        list_del(&f->list);
        printf("after deleted
    ");
        f = list_traverse(&fox_list, handler);
        
        // 同理再删除一个节点
        list_del(&f->list);
        printf("after deleted
    ");
        list_traverse(&fox_list, handler);
        
        return 0;
    }
    

      output:

    tail length: 40, weight=6, fantasic: 0

    tail length: 35, weight=5, fantasic: 1

    after deleted

    tail length: 40, weight=6, fantasic: 0

    after deleted

    Program ended with exit code: 0

  • 相关阅读:
    js中的replace替换全部
    Oracle中创建数据链
    Hbuildx+vue+axios+element ui初学部署
    html5抠图
    Oracle误删除数据的恢复方法
    vs 生成项目自动关闭当前运行程序
    Mvc项目在iis上面显示文件夹 输入地址页面也打不开
    FastReport快速打印(.net)
    脚本之家
    VS自定义作者、创建时间
  • 原文地址:https://www.cnblogs.com/mingzhanghui/p/9377552.html
Copyright © 2011-2022 走看看