Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查数字是否为泛数字的最快算法?_Java_C#_Algorithm - Fatal编程技术网

Java 检查数字是否为泛数字的最快算法?

Java 检查数字是否为泛数字的最快算法?,java,c#,algorithm,Java,C#,Algorithm,泛数字是包含数字1..number长度的数字。 例如123、4312和967412385 我已经解决了许多欧拉项目的问题,但超数字问题总是超过一分钟规则 这是我的泛数字功能: private boolean isPandigital(int n){ Set<Character> set= new TreeSet<Character>(); String string = n+""; for (char c:string.toCharArray

泛数字是包含数字1..number长度的数字。
例如123、4312和967412385

我已经解决了许多欧拉项目的问题,但超数字问题总是超过一分钟规则

这是我的泛数字功能:

private boolean isPandigital(int n){
    Set<Character> set= new TreeSet<Character>();   
    String string = n+"";
    for (char c:string.toCharArray()){
        if (c=='0') return false;
        set.add(c);
    }
    return set.size()==string.length();
}
private boolean isPandigital(int n){
Set=新树集();
字符串字符串=n+“”;
for(char c:string.toCharArray()){
如果(c='0')返回false;
增加(c);
}
返回set.size()==string.length();
}
创建自己的函数并使用此方法进行测试

int pans=0;
for (int i=123456789;i<=123987654;i++){
    if (isPandigital(i)){
         pans++;
    }
}
intpans=0;

对于(inti=123456789;i您可以改进的两件事:

  • 不需要使用集合:可以使用包含10个元素的布尔数组
  • 使用除法和模运算(%)来提取数字,而不是转换为字符串
您可以添加:

 if (set.add(c)==false) return false;
这将大大缩短您的计算时间,因为一旦找到重复项,它将返回false,因为在这种情况下返回false。

这是我的解决方案:

static char[][] pandigits = new char[][]{
        "1".toCharArray(),
        "12".toCharArray(),
        "123".toCharArray(),
        "1234".toCharArray(),
        "12345".toCharArray(),
        "123456".toCharArray(),
        "1234567".toCharArray(),
        "12345678".toCharArray(),
        "123456789".toCharArray(),
};
private static boolean isPandigital(int i)
{
    char[] c = String.valueOf(i).toCharArray();
    Arrays.sort(c);
    return Arrays.equals(c, pandigits[c.length-1]);
}
在我的(相当慢的)系统上以0.3秒的时间运行循环。

C#,17ms,如果你真的想检查的话

类程序
{
静态bool IsPandigital(int n)
{
整数位数=0;整数计数=0;整数tmp;
对于(;n>0;n/=10,++计数)
{
如果((tmp=数字)=(数字|=1=变换[decreasingpart+1]),首先;
--递减部分);
//整个序列按降序排列,已完成
如果(减少部分<0)屈服断裂;
//在递减分区中找到最小的元素,即
//大于(或等于)递减分区前面的项
int大于等于长度-1;
对于(;较大>递减部分&)
变换[decreasingpart]。第一个>=变换[greater]。第一个;
大——);
//将两者互换
交换(参考变换[递减部分]、参考变换[更大];
//反转递减分区
数组。反转(变换,递减部分+1,长度-递减部分-1);
收益回报申请转换(项目、转换);
}
}
#区域重载
公共静态IEnumerable置换(T[]项)
{
返回排列(项目,空);
}
公共静态IEnumerable置换(IEnumerable项、IComparer比较器)
{
列表=新列表(项目);
返回排列(list.ToArray(),比较器);
}
公共静态IEnumerable置换(IEnumerable项)
{
返回排列(项目,空);
}
#端域重载
#区域效用
公共静态IEnumerable应用程序转换(
T[]项,
IntPair[]转换)
{
for(int i=0;i
我的解决方案涉及总和和乘积。 这是C#格式的,在我的笔记本电脑上运行大约180毫秒:

static int[] sums = new int[] {1, 3, 6, 10, 15, 21, 28, 36, 45};
static int[] products = new int[] {1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

static void Main(string[] args)
{
  var pans = 0;
  for (var i = 123456789; i <= 123987654; i++)
  {
    var num = i.ToString();
    if (Sum(num) == sums[num.Length - 1] && Product(num) == products[num.Length - 1])
      pans++;
  }
  Console.WriteLine(pans);
}

protected static int Sum(string num)
{
  int sum = 0;
  foreach (char c in num)
    sum += (int) (c - '0');

  return sum;
}

protected static int Product(string num)
{
  int prod = 1;
  foreach (char c in num)
    prod *= (int)(c - '0');

  return prod;
}
static int[]sums=新的int[]{1,3,6,10,15,21,28,36,45};
静态int[]产品=新int[]{1,2,6,24,120,720,5040,40320,362880};
静态void Main(字符串[]参数)
{
var-pans=0;
对于(var i=123456789;i

为什么要在你能做的时候找到呢


J很好地做到了这一点:

isPandigital =: 3 : 0 *./ (' ' -.~ ": 1 + i. # s) e. s =. ": y ) isPandigital"0 (123456789 + i. 1 + 123987654 - 123456789) isPandigital=:3:0 *./(''-.~“:1+i.#s)e.s=.“:y ) isPandigital“0(123456789+i.1+123987654-123456789) 但是慢慢地。我会修改。现在,计时4.8秒

编辑:

如果它正好位于两个集合编号123456789和123987654之间,则此表达式:

*./"1 (1+i.9) e."1 (9#10) #: (123456789 + i. 1 + 123987654 - 123456789) *./“1(1+i.9)e.”1(9#10)#:(123456789+i.1+123987654-123456789) 运行时间为0.23秒。与J中的速度一样快,是蛮力风格。

bool IsPandigital(无符号长n){
bool IsPandigital (unsigned long n) {
  if (n <= 987654321) {
      hash_map<int, int> m;
      unsigned long count = (unsigned long)(log((double)n)/log(10.0))+1;

      while (n) {
          ++m[n%10];
          n /= 10;
      }

      while (m[count]==1 && --count);

      return !count;
  }

  return false;
}

bool IsPandigital2 (unsigned long d) {
  // Avoid integer overflow below if this function is passed a very long number
  if (d <= 987654321) {
      unsigned long sum = 0;
      unsigned long prod = 1;
      unsigned long n = d;

      unsigned long max = (log((double)n)/log(10.0))+1;
      unsigned long max_sum = max*(max+1)/2;
      unsigned long max_prod = 1;

      while (n) {
          sum += n % 10;
          prod *= (n%10);
          max_prod *= max;
          --max;
          n /= 10;
      }

      return (sum == max_sum) && (prod == max_prod);
  }

如果(n机器管理员是正确的。至少对于一些问题,最好迭代所有的泛数字,检查每个泛数字是否符合问题的标准。但是,我认为他们的代码不太正确

在这种情况下,我不确定哪一个更好:发布新答案还是编辑他们的答案。无论如何,我认为这是修改后的Python代码,尽管它不会生成0到n的泛数字

from itertools import *

def generate_pandigital(length):
    'Generate all 1-to-length pandigitals'
    return (''.join(each) for each in list(permutations('123456789'[:length])))

def test():
    for i in range(10):
        print 'Generating all %d-digit pandigitals' % i
        for (n,p) in enumerate(generate_pandigital(i)):
            print n,p

if __name__=='__main__':
    test()
在123456789到123987654的范围内,这个c#实现比@andras快8%左右,但在我的测试盒上很难看到他的运行时间是14毫秒,而这个运行时间是13毫秒

static bool IsPandigital(int n)
{
    int count = 0;
    int digits = 0;
    int digit;
    int bit;
    do
    {
        digit = n % 10;
        if (digit == 0)
        {
            return false;
        }
        bit = 1 << digit;

        if (digits == (digits |= bit))
        {
            return false;
        }

        count++;
        n /= 10;
    } while (n > 0);
    return (1<<count)-1 == digits>>1;
}
static bool IsPandigital(int n)
{
整数计数=0;
整数位数=0;
整数位数;
整数位;
做
{
数字=n%10;
如果(数字==0)
{
返回false;
}
位=1 0);
返回(11;
}
如果我们平均100次运行的结果,我们可以得到一个小数点

public void Test()
{
    int pans = 0;
    var sw = new Stopwatch();
    sw.Start();
    for (int count = 0; count < 100; count++)
    {
        pans = 0;
        for (int i = 123456789; i <= 123987654; i++)
        {
            if (IsPandigital(i))
            {
                pans++;
            }
        }
    }
    sw.Stop();
    Console.WriteLine("{0}pcs, {1}ms", pans, sw.ElapsedMilliseconds / 100m);
}
公共无效测试()
{
int pans=0;
var sw=新秒表();
sw.Start();
用于(int count=0;count<100;count++)
{
pans=0;
对于(int i=123456789;i 1;
}
编辑:将n/=10集成到数字计算中,以实现小的速度改进
bool IsPandigital (unsigned long n) {
  if (n <= 987654321) {
      hash_map<int, int> m;
      unsigned long count = (unsigned long)(log((double)n)/log(10.0))+1;

      while (n) {
          ++m[n%10];
          n /= 10;
      }

      while (m[count]==1 && --count);

      return !count;
  }

  return false;
}

bool IsPandigital2 (unsigned long d) {
  // Avoid integer overflow below if this function is passed a very long number
  if (d <= 987654321) {
      unsigned long sum = 0;
      unsigned long prod = 1;
      unsigned long n = d;

      unsigned long max = (log((double)n)/log(10.0))+1;
      unsigned long max_sum = max*(max+1)/2;
      unsigned long max_prod = 1;

      while (n) {
          sum += n % 10;
          prod *= (n%10);
          max_prod *= max;
          --max;
          n /= 10;
      }

      return (sum == max_sum) && (prod == max_prod);
  }
from itertools import *

def generate_pandigital(length):
    'Generate all 1-to-length pandigitals'
    return (''.join(each) for each in list(permutations('123456789'[:length])))

def test():
    for i in range(10):
        print 'Generating all %d-digit pandigitals' % i
        for (n,p) in enumerate(generate_pandigital(i)):
            print n,p

if __name__=='__main__':
    test()
static bool IsPandigital(int n)
{
    int count = 0;
    int digits = 0;
    int digit;
    int bit;
    do
    {
        digit = n % 10;
        if (digit == 0)
        {
            return false;
        }
        bit = 1 << digit;

        if (digits == (digits |= bit))
        {
            return false;
        }

        count++;
        n /= 10;
    } while (n > 0);
    return (1<<count)-1 == digits>>1;
}
public void Test()
{
    int pans = 0;
    var sw = new Stopwatch();
    sw.Start();
    for (int count = 0; count < 100; count++)
    {
        pans = 0;
        for (int i = 123456789; i <= 123987654; i++)
        {
            if (IsPandigital(i))
            {
                pans++;
            }
        }
    }
    sw.Stop();
    Console.WriteLine("{0}pcs, {1}ms", pans, sw.ElapsedMilliseconds / 100m);
}
private static bool IsPandigital(int n)
{
    int count = 0;
    int digits = 0;
    int digit;
    int bit;
    do
    {
        digit = n - ((n / 10) * 10);
        if (digit == 0)
        {
            return false;
        }
        bit = 1 << digit;

        if (digits == (digits |= bit))
        {
            return false;
        }

        count++;
        n /= 10;
    } while (n > 0);
    return (1 << count) - 1 == digits >> 1;
}
private static bool IsPandigital(int n)
{
    int count = 0;
    int digits = 0;
    int digit;
    int bit;
    do
    {
        digit = n - ((n /= 10) * 10);
        if (digit == 0)
        {
            return false;
        }
        bit = 1 << digit;

        if (digits == (digits |= bit))
        {
            return false;
        }

        count++;
    } while (n > 0);
    return (1 << count) - 1 == digits >> 1;
}
public class GenPandigits 
{

 /**
 * The prefix that must be appended to every number, like 123.
 */
int prefix;

/**
 * Length in characters of the prefix.
 */
int plen;

/**
 * The digit from which to start the permutations
 */
String beg;

/**
 * The length of the required Pandigital numbers.
 */
int len;

/**
 * @param prefix If there is no prefix then this must be null
 * @param beg If there is no prefix then this must be "1"
 * @param len Length of the required numbers (excluding the prefix)
 */
public GenPandigits(String prefix, String beg, int len)
{
    if (prefix == null) 
    {
        this.prefix = 0;
        this.plen = 0;
    }
    else 
    {
        this.prefix = Integer.parseInt(prefix);
        this.plen = prefix.length();
    }
    this.beg = beg;
    this.len = len;
}
public StringBuffer genPermsBet()
{
    StringBuffer b = new StringBuffer(beg);
    for(int k=2;k<=len;k++)
    {
        StringBuffer rs = new StringBuffer();
        int l = b.length();
        int s = l/(k-1);
        String is = String.valueOf(k+plen);
        for(int j=0;j<k;j++)
        {
            rs.append(b);
            for(int i=0;i<s;i++)
            {
                rs.insert((l+s)*j+i*k+j, is);
            }
        }
        b = rs;
    }
    return b;
}

public int[] getPandigits(String buffer)
{
    int[] pd = new int[buffer.length()/len];
    int c= prefix;
    for(int i=0;i<len;i++)
        c =c *10;
    for(int i=0;i<pd.length;i++)
        pd[i] = Integer.parseInt(buffer.substring(i*len, (i+1)*len))+c;
    return pd;
}
public static void main(String[] args) 
{
    GenPandigits gp = new GenPandigits("123", "4", 6);

    //GenPandigits gp = new GenPandigits(null, "1", 6);

    long beg = System.currentTimeMillis();
    StringBuffer pansstr = gp.genPermsBet();
    long end = System.currentTimeMillis();
    System.out.println("Time = " + (end - beg));
    int pd[] = gp.getPandigits(pansstr.toString());
    long end1 = System.currentTimeMillis();
    System.out.println("Time = " + (end1 - end));
    }
}
GenPandigits gp = new GenPandigits(null, "1", 9);
bool IsPandigital(int n)
{
    if (n != 9 * (int)((0x1c71c71dL * n) >> 32))
        return false;

    int flags = 0;
    while (n > 0) {
        int q = (int)((0x1999999aL * n) >> 32);
        flags |= 1 << (n - q * 10);
        n = q;
    }
    return flags == 0x3fe;
}
#include <cstdio>
#include <ctime>

bool isPandigital(long num)
{
  int arr [] = {1,2,3,4,5,6,7,8,9}, G, count = 9;
  do
  {
    G = num%10;
    if (arr[G-1])
      --count;
    arr[G-1] = 0;
  } while (num/=10);

  return (!count);
}

int main()
{
  clock_t start(clock());

  int pans=0;
  for (int i = 123456789;i <= 123987654; ++i)
  {
    if (isPandigital(i))
      ++pans;
  }

  double end((double)(clock() - start));

  printf("\n\tFound %d Pandigital numbers in %lf seconds\n\n", pans, end/CLOCKS_PER_SEC);

  return 0;
}
public static List<String> permutation(String str) {
    List<String> permutations = new LinkedList<String>();
    permutation("", str, permutations);
    return permutations;
}

private static void permutation(String prefix, String str, List<String> permutations) {
    int n = str.length();
    if (n == 0) {
        permutations.add(prefix);
    } else {
        for (int i = 0; i < n; i++) {
            permutation(prefix + str.charAt(i),
                    str.substring(0, i) + str.substring(i + 1, n), permutations);
        }
    }
}
public static boolean is1To9PanDigit(int i) {
    if (i < 1e8) {
        return false;
    }
    BitSet set = new BitSet();
    while (i > 0) {
        int mod = i % 10;
        if (mod == 0 || set.get(mod)) {
            return false;
        }
        set.set(mod);
        i /= 10;
    }
    return true;
}
public static boolean is1ToNPanDigit(int i, int n) {
    BitSet set = new BitSet();
    while (i > 0) {
        int mod = i % 10;
        if (mod == 0 || mod > n || set.get(mod)) {
            return false;
        }
        set.set(mod);
        i /= 10;
    }
    return set.cardinality() == n;
}
public static boolean is0To9PanDigit(long i) {
    if (i < 1e6) {
        return false;
    }
    BitSet set = new BitSet();
    if (i <= 123456789) { // count for leading zero
        set.set(0);
    }
    while (i > 0) {
        int mod = (int) (i % 10);
        if (set.get(mod)) {
            return false;
        }
        set.set(mod);
        i /= 10;
    }
    return true;
}
public static int maxPanDigit(int n) {
    StringBuffer sb = new StringBuffer();
    for(int i = n; i > 0; i--) {
        sb.append(i);
    }
    return Integer.parseInt(sb.toString());
}

public static int minPanDigit(int n) {
    StringBuffer sb = new StringBuffer();
    for(int i = 1; i <= n; i++) {
        sb.append(i);
    }
    return Integer.parseInt(sb.toString());
}
def is_pandigital(n, zero_full=True, base=10): """Returns True or False if the number n is pandigital. This function returns True for formal pandigital numbers as well as n-pandigital """ r, l = 0, 0 while n: l, r, n = l + 1, r + n % base, n / base t = xrange(zero_full ^ 1, l + (zero_full ^ 1)) return r == sum(t) and l == len(t)
boolean isPandigital(int num,int length){
    for(int i=1;i<=length;i++){
        if(!(num+"").contains(i+""))
            return false;
    }
    return true;
}
static boolean isPandigital(int num){
    for(int i=1;i<=(num+"").length();i++){
        if(!(num+"").contains(i+""))
            return false;
    }
    return true;
}
extension Int {

    func isPandigital() -> Bool {

        let requiredBitmask = 0b1111111111;
        let minimumPandigitalNumber = 1023456789;

        if self >= minimumPandigitalNumber {

            var resultBitmask = 0b0;
            var digits = self;

            while digits != 0 {

                let lastDigit = digits % 10;
                let binaryCodedDigit = 1 << lastDigit;

                resultBitmask |= binaryCodedDigit;

                // remove last digit
                digits /= 10;
            }

            return resultBitmask == requiredBitmask;
        }

        return false;
    }
}


1023456789.isPandigital(); // true
bool IsPandigital(long long number, int n){

int arr[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, amax = 0, amin;
while (number > 0){

    int rem = number % 10;

    arr[rem]--;

    if (arr[rem] < 0)
        return false;

    number = number / 10;
}

for (int i = 0; i < n; i++){

    if (i == 0)
        amin = arr[i];

    if (arr[i] > amax)
        amax = arr[i];

    if (arr[i] < amin)
        amin = arr[i];
}

if (amax == 0 && amin == 0)
    return true;
else
    return false;