2015-07-16 13 views
6

Tôi hoàn toàn bối rối về một vấn đề và muốn một số hướng dẫn. Tôi chọn các tập hợp ngẫu nhiên gồm 8 số từ tập 1 đến 8 (ví dụ, 5,6,8,1,3,4,2,7) và cố gắng gộp các con số đó dưới dạng tập con của các số thứ tự theo thứ tự họ xuất hiện.Vượt qua trong R hoặc SQL

Ví dụ ở trên, nhóm đầu tiên sẽ bắt đầu bằng số 5 thì 6 sẽ được thêm vào. Khi nhấn 8 một thùng mới sẽ được bắt đầu. Bất cứ khi nào chúng tôi nhận được một số thuộc về một nhóm hiện có (ví dụ: khi chúng tôi đạt đến 2, nó có thể được thêm vào nhóm của 1), chúng tôi thêm nó vào đó. Trong ví dụ này, sau tất cả 8 số, chúng tôi sẽ đến:

5,6,7 
8 
1,2 
3,4 

Tổng cộng có 4 nhóm.

Tôi không thực sự quan tâm đến nội dung của các nhóm, tôi chỉ muốn đếm số lượng nhóm có cho một tập hợp ngẫu nhiên 8 chữ số. Tôi dự định lặp qua một bộ 1000 trong số 8 dãy số này.

+2

Tôi không hiểu logic đằng sau điều này. 7 không xuất hiện trong chuỗi đầu tiên. Không phải 2 trong phần ba. –

+1

Vì vậy, ý tưởng là chúng tôi đang đi qua chữ số bằng chữ số, tạo một nhóm mới nếu một số không theo thứ tự khi có bất kỳ nhóm nào trước đó. Vì vậy, 5 tạo ra đầu tiên, 6 đi vào nó. 8 Tạo nhóm thứ hai. 1 tạo ra thứ ba. 3 tạo ra thứ 4. Sau đó, 4,2 và 7 được nối thêm vào các nhóm hiện có (vì chúng nằm trong chuỗi). Odd vấn đề, có, nhưng loại một trong những thú vị. –

+2

Vì vậy, sắp xếp như tạo ngăn xếp Solitaire ... – MichaelChirico

Trả lời

2

Tôi không quá quen thuộc với R, nhưng bạn chắc chắn có thể làm điều gì đó như:

setOf8 = your array of 8 numbers 
buckets=0 
for(i = [2,8]) 
{ 
    if((setOf8[i] < setOf8[i-1])) 
    { 
     buckets = buckets + 1 
    } 
} 

EDIT:

Bạn có thể làm một cái gì đó như:

func countBuckets(buckets, set) 
{ 
    set = your array 
    current = 1 
    for(i = [2,size(set)]) 
    { 
     if(set[current] + 1 == set[i]) 
     { 
      set.remove(current) 
      current = set[i-1] 
     } 
    } 
    if(size(set) == 0) 
    { 
     return buckets 
    } 
return countBuckets(buckets + 1, set) 
} 
+0

Cảm ơn. Tôi đã bắt đầu với một cái gì đó như thế, nhưng vấn đề xảy ra với những con số như 7 cuối cùng, nó không theo thứ tự, nhưng nó không bắt đầu một xô mới. Nó cần phải được nối thêm vào nhóm đầu tiên. –

+0

Tôi không định dạng được, hãy xem bài đăng đã chỉnh sửa. – Brian

5

Nếu bạn là chỉ quan tâm đến số lượng nhóm,

## Your data 
dat <- c(5,6,8,1,3,4,2,7) 

## Get the number of buckets 
count <- 0 
for (i in seq_along(dat)) 
    if (!((dat[i] - 1) %in% dat[1:i])) count <- count+1 
count 
# 4 

và, một cách ngắn gọn hơn trong một chức năng

countBuckets <- function(lst) sum(sapply(1:length(lst), function(i) 
    (!((lst[i]-1) %in% lst[1:i])))) 

Và, đây là một thực hiện đệ quy để có được nội dung của xô.

f <- function(lst, acc=NULL) { 
    if (length(lst) == 0) return(acc) 
    if (missing(acc)) return(Recall(lst[-1], list(lst[1]))) 

    diffs <- sapply(acc, function(x) lst[1] - x[length(x)] == 1) 
    if (any(diffs)) { 
     acc[[which(diffs)]] <- c(acc[[which(diffs)]], lst[1]) 
    } else { acc <- c(acc, lst[1]) } 
    return (Recall(lst[-1], acc)) 
} 

f(dat) 

# [[1]] 
# [1] 5 6 7 
# 
# [[2]] 
# [1] 8 
# 
# [[3]] 
# [1] 1 2 
# 
# [[4]] 
# [1] 3 4 
+2

Câu trả lời này không nhận được sự đánh giá cao xứng đáng của nó –

2

Tôi không chắc chắn làm thế nào nó sẽ triền Oracle, nhưng kể từ khi bạn đã thêm Server thẻ SQL, đây là một giải pháp T-SQL:

declare @set char(8) = '56813427'; 

with cte as (
    select s.Id, cast(substring(@set, s.Id, 1) as int) as [Item] 
    from dbo.Sequencer s 
    where s.Id between 1 and 8 
    union all 
    select 9 as [Id], 0 as [Item] 
) 
select count(*) as [TotalBuckets] 
from cte s 
    inner join cte n on (s.Item = n.Item - 1) and s.Id > n.Id; 

Ý tưởng đằng sau nó là đếm các trường hợp khi số tiếp theo đi trước số hiện tại, bắt đầu một nhóm mới thay vì tiếp tục một nhóm hiện tại. Vấn đề duy nhất ở đây là với ranh giới, vì vậy tôi đã thêm dấu 0. Nếu không có nó, ít nhất là thiết lập mục (1 trong trường hợp của bạn) không được tính là một xô riêng biệt.

P.S. dbo.Sequencer là một bảng có số nguyên tăng dần. Tôi thường giữ một trong cơ sở dữ liệu để dự án trình tự sắp xếp.

5

Giải pháp của tôi, không được tách từ nongkrong nhưng khá giống nhau. Bạn lấy số liệu của xô:

x <- as.integer(c(5,6,8,1,3,4,2,7)) 
sum(is.na(sapply(1:length(x), function(i) which((x[i]-1L)==x[1:i])[1L]))) 
# [1] 4 

tôi tin rằng nó có thể vectorize nó, sau đó nó sẽ mở rộng quy mô một cách hoàn hảo.

+0

chỉ chạy trên 1000 bản sao, đó là PDQ đã – MichaelChirico

4

Lấy cảm hứng từ @jangorecki nhưng nhanh hơn:

x <- sample(8L) 
1 + sum(sapply(2L:8L, function(i) !any(x[i] - x[1:(i - 1L)] == 1))) 
3

Dưới đây là một câu trả lời vectorized:

ind.mat <- matrix(rep(1:8, each=8), ncol=8) 
ind.mat[upper.tri(ind.mat)] <- NA 
8 - sum(rowSums(matrix(rep(x, 8), ncol=8) - x[ind.mat] == 1, na.rm=TRUE)) 

Lưu ý rằng chúng ta chỉ cần khai báo ind.mat lần, vì vậy quy mô lên tốt để nhân rộng.

+1

Ngoài ra nó sẽ nhận được một tốc độ lớn hơn nhiều nếu OP có thể cung cấp tất cả 1000 trường hợp và xây dựng một ma trận duy nhất trên chúng. Trong việc thực hiện bi quan nhất, id trường hợp sẽ tạo thành một thứ nguyên bổ sung trong mảng. – jangorecki

Các vấn đề liên quan